我有一个' M'经理(指挥)实例,控制另外两个实例' A'和' B'。 ' A'是az实体框架数据保护程序,' B'调用外部Web服务来执行某些操作。 ' M'的代码看起来像:
// code inside 'M'
void Save()
B.Save()
A.Save()
这是一种分布式事务。当B.Save掉线异常时,A.Save不应该发生或完成。现在我必须改变它才能运作良好。问题是,' M'什么都不知道EF交易是如何工作的,或者如何处理它,而A.Save不能包含B.Save调用。所以我必须以某种方式改变它:
Object transaction = A.PrepareSave()
try {
B.Save()
}
catch {
A.RollbackSave(transaction)
throw
}
A.FinishSave(transaction)
A.PrepareSave()看起来像(?)
TransactionScope scope = new TransactionScope()
var context = CreateContext()
... do something EF ...
context.SaveChanges(false)
return new MyCustomTuple(scope,context)
A.FinishShave(Object trans)看起来像(?)
MyCustomTuple tuple = (MyCustomTuple)trans
TransactionScope scope = (TransactionScope)tuple.Scope
EFContext context = (EFContext)tuple.Context
scope.Complete()
context.AcceptAllChanges()
问题1:可以吗?这是处理这种情况的方法吗? (我对B.Save()没有影响,它保存或删除异常)
问题2:如何在最后释放资源(范围,背景)? ' M'经理对MyCustomTuple及其内容一无所知。
答案 0 :(得分:1)
您可以在M方法中使用TransactionScope
权限,而不需要在代码的不同部分处理它。
using (var transaction = new TransactionScope())
{
A.Save();
B.Save();
transaction.Complete();
}
如果两个保存方法都完成,这将完成,否则抛出异常,不会调用Complete()
,因此没有提交。 using
块将释放TransactionScope
。至于处理其他资源,您可以像现在这样处理它。您没有包含任何示例(我希望创建上下文的组件,可能是组件A,处理该上下文的处置),