CommitAsync() 的缺点 w/o 对集合的任何更改

Downsides of CommitAsync() w/o any changes to collection

所有示例通常都展示了对可靠集合的某种更改 CommitAsync() 或在出现故障时回滚。我的代码使用的是TryRemoveAsync(),所以失败不是问题(稍后会重试)。

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

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

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

如果集合没有被修改,交易将不会有任何东西 save\replicate 并且只会关闭交易。

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

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

   // 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