【问题标题】:Downsides of CommitAsync() w/o any changes to collection没有对集合进行任何更改的 CommitAsync() 的缺点
【发布时间】:2018-05-14 03:26:12
【问题描述】:

所有示例通常都使用CommitAsync() 或在发生故障时回滚来演示对可靠集合的某种更改。我的代码使用的是TryRemoveAsync(),所以不用担心失败(稍后会重试)。

当没有对可靠集合执行更改时调用 tx.CommitAsync() 是否有明显的缺点?

【问题讨论】:

    标签: azure-service-fabric


    【解决方案1】:

    每当您打开一个事务并对集合执行命令时,这些命令会在 TStore(Collection) 中获取锁,并记录到事务临时字典(更改跟踪)和事务日志中,然后复制器将转发这些对副本的更改。

    一旦你执行tx.CommitAsync(),临时记录被保存到磁盘,事务在日志中注册,然后复制到辅助副本也提交并保存到磁盘,然后释放锁。

    如果集合没有被修改,事务将没有任何东西可以保存\复制,只会关闭事务。

    如果您在操作后不调用tx.CommitAsync(),则事务将被中止并丢弃任何未决操作(如果有)并将中止操作写入日志以通知其他副本。

    在这两种情况下,Commit 和 Abort 都会生成日志(并复制它们),我不确定的唯一细节是这些日志是否也在没有更改的情况下生成,我假设它们是。关于性能,读取或尝试更改集合的行为将获取锁并需要通过提交或中止释放,我认为这些对您的代码影响最大,因为它们会阻止其他线程在您修改它时没有完成交易。在这种情况下,我不会太担心提交一个空事务。

       // Create a new Transaction object for this partition
       using (ITransaction tx = base.StateManager.CreateTransaction()) {
          //modify the collection
          await m_dic.AddAsync(tx, key, value, cancellationToken);
    
          // CommitAsync sends Commit record to log & secondary replicas
          // After quorum responds, all locks released
          await tx.CommitAsync();
       } // If CommitAsync not called, this line will Dispose the transaction and discard the changes
    

    您可以在documentation 上找到大部分这些详细信息

    如果你真的想深入了解实现细节来回答这个问题,我建议你在复制器的源代码中挖掘答案here

    【讨论】:

    • 谢谢迭戈。我的问题是关于未修改集合但提交事务时的性能影响。
    • 我已经用一些额外的信息更新了答案,除此之外,我不知道,我已经添加了复制器源代码的链接,我想你会找到答案的其余部分在那里,或者等待 SF 团队的人提供更好的答案。
    • “我不会太担心提交一个空事务。”。我现在投了赞成票,因为我认为您提供了很好的信息并且倾向于同意不应该对性能产生任何重大影响。将查看 SF 团队的任何内容是否会适当地回答和标记。再次感谢您。
    • 确认一般观点:在没有更改的情况下调用 Commit 没有任何开销或问题。 SF 指导将始终明确调用 Commit 或 Abort,即使没有任何更改。
    猜你喜欢
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 2016-06-02
    • 2017-05-31
    • 2019-09-19
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多