2011-08-26 60 views
0

我对EF和事务处理有点问题。EF Transactions MSDTC?

我试图做到这一点:

using(TransactionScope scope = new TransactionScope()) 
{ 
    using(MyEntities model = new MyEntities()) 
    { 
    MyT thing = new MyT{ Value1 = "bla", Value2 = "bla2", Value3 = "foo" }; 
    model.MyT.AddObject(thing); 
    model.SaveChanges(); 

    thing.Value4 = Service.Call("bar"); 

    // this call causes an exception in MSDTC 
    model.SaveChanges(); 

    scope.Complete(); 
    } 
} 

我之所以这样做是因为我想做一个插入到数据库所以MYT有一个唯一的ID我passto服务当我做该电话然后从服务中获取唯一的参考和状态,描述在通话期间发生了什么,然后我需要追加到记录中。

我的理解是,一个单一的交易过程中,你只能更新记录一次/使插入电话,但你不能这样做既因为这会产生某种原因出现问题......我曾经有一个MSDN文章说解释了为什么无法完成这个逻辑原因(可能与锁有关)。

所以我的问题是如何克服这个,但是保证在任何这些调用我仍然可以回滚的任何故障的事件。

+0

你有什么问题吗?你发布的代码是如何工作的?它看起来对我好。 –

+0

什么是例外? – JNappi

+0

异常是一个com +异常,它简单地读取“在com +对象中发生的异常”,就是这样...事件中没有记录任何没有帮助的异常。 – War

回答

1

当您在事务范围内与数据库建立多个连接时,事务将从本地事务提升为分布式事务,除非您明确地使用与db相同的连接。

当交易被提升需要MSDTC服务来管理事务,所以如果此服务不存在,它会抛出异常。

事情是这样的:

using(TransactionScope scope = new TransactionScope()) 
{ 
    using(MyEntities model = new MyEntities()) 
    { 
    model.Connection.Open(); 
    MyT thing = new MyT{ Value1 = "bla", Value2 = "bla2", Value3 = "foo" }; 
    model.MyT.AddObject(thing); 
    model.SaveChanges(); 

    thing.Value4 = Service.Call("bar"); 

    // this call shouldn't cause anymore an exception in MSDTC 
    model.SaveChanges(); 

    scope.Complete(); 
    } 
} 
+0

该服务正在运行,但这会导致进一步的复杂性,因为它决定它会给出一个com +异常,在任何日志中没有任何有价值的东西,或者在例外情况下给出bac。 – War

+1

尽可能避免使用MSDTC会更高效,请尝试明确设置连接以避免它。 – TrymBeast

+0

MSDTC升级的另一个变体是在事务中多次打开和关闭连接(尽管我认为这已在新版本的框架中得到修复)。尝试重新使用打开的连接,并在交易结束时关闭它。 –