考虑
foreach (var myEntity in myEntities)
{
using (TransactionScope scope = new TransactionScope())
{
// Some not very important code
myEntity.ImageUrl = FixUrl(myEntity.ImageUrl);
MyEntity additionalEntity = Clone(myEntity);
additionalEntity.DateCreated = DateTime.Now;
additionalEntity.CreatedBy = GetCurrentUser();
//Step 1
serverDbContext.Update(myEntity);
//Step 2
AddToQueue(myEntity);
//Step 3
anotherserverDbContext.Insert(myEntity);
scope.Complete();
}
}
请注意,TransactionScope是在foreach语句中创建的。尝试使用此代码确认交易范围是昂贵的操作。
预计AddToQueue有时会抛出异常。在这种情况下,我们不希望在server1数据库中,也不希望在server2数据库中对该实体进行任何更改。
如果没有事务范围,此代码将在几秒钟内执行,而使用on执行则需要永久执行。 我真正想要的是在1,2或3步中的任何一个例外情况下仍然无法改变基础记录。
显然,使用移动内部的foreach是不够的,因为如果一个循环的至少一次传递失败,那么好的记录也可能会被破坏而且什么都不会更新。
我需要了解更多关于交易机制的信息,或者可以在这里尝试其他什么工具?
答案 0 :(得分:1)
TransactionScope
价格昂贵,因为交易费用很高。
如果您希望保证一致性,但又不想将整个操作作为一个工作单元,那么如果您将其并行化,则可能会发现操作完成得更快。实现这一目标的一种简单方法是使用Parallel.ForEach
:
myEntities.AsParallel().ForEach(entity =>
{
using (TransactionScope scope = new TransactionScope())
{
// The operation to perform in parallel.
scope.Complete();
}
}
显然这引入了异步处理,因此您需要小心在并发运行的循环中共享的任何对象。
如果这不是一个选项,唯一的另一个实际选择是放弃原子一致性并转移到最终一致性系统。在这种情况下,它意味着在没有作用域的情况下运行,然后执行常规的“清理”操作来撤消任何不一致状态的“坏”记录。