没有对集合进行任何更改的CommitAsync()的缺点 [英] Downsides of CommitAsync() w/o any changes to collection

查看:147
本文介绍了没有对集合进行任何更改的CommitAsync()的缺点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所有样本通常都会通过CommitAsync()展示出对可靠集合的某种更改,或者在发生故障的情况下回滚.我的代码使用的是TryRemoveAsync(),因此不必担心失败(稍后会重试).

All the samples usually demonstrate some sort of change to reliable collections with CommitAsync() or rollback in case of a failure. My code is using TryRemoveAsync(), so failure is not a concern (will be retried later).

在未对可靠集合进行任何更改的情况下,调用tx.CommitAsync()是否有重大不利之处?

Is there a significant downside to invoking tx.CommitAsync() when no changes to reliable collections where performed?

推荐答案

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

Whenever you open a Transaction and execute commands against a collection, these commands acquire locks in the TStore(Collection) and are recorded to the transaction temporary dictionary(Change tracking) and also to the transaction logs, the replicator then will forward these changes to the replicas.

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

Once you execute the tx.CommitAsync() the temporary records are saved to the disk, the transaction is registered in the logs and then replicated to secondary replicas to also commit and save to the disk, and then the locks are released.

如果未修改集合,则事务将没有任何保存\复制操作,只会关闭事务.

If the collection is not modified, the transaction won't have anything to save\replicate and will just close the transaction.

如果您在操作后未调用tx.CommitAsync(),则事务将中止并且所有挂起的操作(如果有)将被丢弃,并将中止操作写入日志以通知其他副本.

If you don't call tx.CommitAsync() after the operation, the transaction is aborted and any pending operations(if any) are discarded and the abort operation is written to the logs to notify other replicas.

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

In both cases, Commit and Abort, will generate logs(and replicate them), The only detail I am not sure is if these logs are also generated when no changes are in place, I assume they are. Regarding performance, the act of reading or attempting to change a collection, will acquire locks and need to be released with a commit or abort, I think these are to biggest impact on your code, because they will prevent other threads of modifying it while you not complete the transaction. In this case I wouldn't be too worried committing an empty transaction.

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

您可以在文档

如果您真的想深入了解实现细节以回答此问题,建议您在复制器的源代码中找到答案

If you really want to go deep on implementation details to answer this question, I suggest you dig the answer in the source code for the replicator here

这篇关于没有对集合进行任何更改的CommitAsync()的缺点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆