分布式两步交易,包括EF和Web服务调用

时间:2017-05-02 08:52:58

标签: c# entity-framework transactions distributed

我有一个' 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及其内容一无所知。

1 个答案:

答案 0 :(得分:1)

您可以在M方法中使用TransactionScope权限,而不需要在代码的不同部分处理它。

using (var transaction = new TransactionScope())
{
  A.Save();
  B.Save();
  transaction.Complete();
}

如果两个保存方法都完成,这将完成,否则抛出异常,不会调用Complete(),因此没有提交。 using块将释放TransactionScope。至于处理其他资源,您可以像现在这样处理它。您没有包含任何示例(我希望创建上下文的组件,可能是组件A,处理该上下文的处置),