所有样本通常都会对CommitAsync()
的可靠集合进行某种更改,或者在出现故障时进行回滚。我的代码使用TryRemoveAsync()
,因此失败不是问题(将在稍后重试)。
在没有对可靠集合进行更改的情况下调用tx.CommitAsync()
是否存在重大缺点?
答案 0 :(得分:2)
每当您打开一个Transaction并对集合执行命令时,这些命令会获取TStore(Collection)中的锁并记录到事务临时字典(Change tracking)以及事务日志中,然后复制器将转发这些命令对副本的更改。
执行tx.CommitAsync()
后,临时记录将保存到磁盘,事务将在日志中注册,然后复制到辅助副本以提交并保存到磁盘,然后释放锁。
如果未修改集合,则事务无法保存\复制,只会关闭事务。
如果您在操作后没有调用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