【发布时间】:2018-05-14 03:26:12
【问题描述】:
所有示例通常都使用CommitAsync() 或在发生故障时回滚来演示对可靠集合的某种更改。我的代码使用的是TryRemoveAsync(),所以不用担心失败(稍后会重试)。
当没有对可靠集合执行更改时调用 tx.CommitAsync() 是否有明显的缺点?
【问题讨论】:
所有示例通常都使用CommitAsync() 或在发生故障时回滚来演示对可靠集合的某种更改。我的代码使用的是TryRemoveAsync(),所以不用担心失败(稍后会重试)。
当没有对可靠集合执行更改时调用 tx.CommitAsync() 是否有明显的缺点?
【问题讨论】:
每当您打开一个事务并对集合执行命令时,这些命令会在 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
【讨论】: