MSDTC问题与ADO.NET实体框架中的事务

问题描述:

在我们当前的项目中,我们使用ADO.NET实体框架作为应用程序的数据层。有一些任务需要在事务中运行,因为数据库中有很多工作要做。我正在使用TransactionScope来围绕这些任务。MSDTC问题与ADO.NET实体框架中的事务

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew)) 
{ 
    // Do something... 
    transactionScope.Complete(); 
} 

的问题,一旦是我使用的是TransactionScope发生异常:

System.Data.EntityException:底层提供失败的打开。 ---> System.Transactions.TransactionManagerCommunicationException:与底层事务管理器的通信失败。 ---> System.Runtime.InteropServices.COMException(0x80004005):错误HRESULT E_FAIL已从调用返回到COM组件。

看来,这个错误必须与MSDTC(Microsoft分布式事务处理协调器)做些什么。当我更改MSDTC的安全配置时,会引发另一个异常:

System.Data.EntityException:底层提供程序在打开时失败。 ---> System.Transactions.TransactionManagerCommunicationException:分布式事务管理器(MSDTC)的网络访问已被禁用。请使用组件服务管理工具在MSDTC的安全配置中启用DTC以进行网络访问。

但是,配置了MSDTC,TransactionScope将导致错误。 有人知道这里出了什么问题吗?

嗯,看来上班的时候我改变TransactionScopeOption为“禁止”:

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress)) 
{ 
    ... 
} 

是否每个人都知道为什么吗?

+4

我认为它在这种情况下根本不使用交易,但我不确定。 – 2009-10-27 10:54:56

+0

是的,这个选项表明它不应该参与交易。 – 2010-03-17 10:33:55

+1

我得到了同样的错误,但是这不是最好的答案。 – 2010-07-30 12:41:16

默认情况下MSDTC禁用网络访问。得到它的工作,你应该去

控制面板 - >管理工具 - >组件服务 - >组件 Serivces-> Computes->我的电脑 - >右键单击 - >属性 - > MSDTC->安全 配置

,并检查下列复选框网络DTC访问,允许入站,允许出站。鉴别应根据你的环境来选择。您可能还想看看DTCPing工具来调试分布式事务。为了给你一个快捷方式 - 你可能需要修改你的注册表:

HKLM \ SOFTWARE \政策\微软\的Windows NT \ RPCRestrictRemoteClients = 0 HKLM \ SOFTWARE \政策\微软\的Windows NT \ RPCEnableAuthEpResolution = 1

让所有东西都能正常运行。

+0

感谢,DTCPing工具告诉我,有一些RPC终结点错误。现在我正在检查http://support.microsoft.com/kb/306843&http://support.microsoft.com/kb/839880/EN-US/也许这就是解决方案。 – Alexander 2009-10-23 09:02:57

+0

对于Windows 8,可以在这里找到“安全配置”: http://*.com/questions/7694/how-do-i-enable-msdtc-on-sql-server/27263904#27263904 – 2015-06-03 20:04:28

这意味着它被抑制,当你输入你的代码块,可能是在效果目前任何交易,因此,如果外部“环境”的交易决定回滚您的代码的任何更新将不会回滚。

这是我们在解决我们自己的,类似的问题使用的文章:

Troubleshooting Problems with MSDTC

这基本上是一个增编Nikolay R's答案。他已经介绍了文章中列出的一些建议。

注意:本文是Biztalk文档的一部分,但它可以应用于任何使用MSDTC的应用程序。

+0

已更新类似文章 http://msdn.microsoft.com/en-us/library/aa561924.aspx – JeremyWeir 2012-06-28 17:20:32

是的,它使用Supress,因为您告诉它禁止或忽略环境事务并创建新的本地事务。由于交易是本地的,它不是一个分布式交易,所以它不使用MSDTC,但你可能不应该使用Suppress,而应该使用Required。

“如果您使用实体框架和事务,实体框架将自动打开并关闭与每个数据库调用的连接,因此在使用事务时,您试图通过多个连接传出事务,从而升级到MSDTC。

您可以将数据库上下文传递给事务中的被调用者类或函数。

也许这就是你的答案:MSSQL Error 'The underlying provider failed on Open'

,如果你想运行一些代码,可能会失败Supressing交易是有用的,但你不想放弃,因为失败的交易。

,你需要问自己的问题是: 你在你的TransactionScope访问超过1个耐用资源?我的意思是,你打开超过1个数据库的连接吗?

这是一个重要的问题,因为如果您访问多个持久资源,交易将升级为DTC。

支持单相通知

至少两种持久资源入伍交易。例如,征用单个连接不会导致事务被提升。但是,无论何时打开数据库的第二个连接导致数据库登记,System.Transactions基础结构都会检测到它是事务中的第二个持久资源,并将其升级为MSDTC事务。 来源:

//Create rootScope 
using(TransactionScope rootScope = new TransactionScope()) 
{ 
    using(TransactionScope scope2 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    { 
     //Do work on DB1 
     ... 

     //Complete this ambient transaction 
     scope2.Complete(); 
    } 

    using(TransactionScope scope3 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    { 
     //Do work on DB2 
     ... 

     //Complete this ambient transaction 
     scope3.Complete(); 
    } 

    //Complete rootScope 
    //The whole transaction will only be committed if you call 
    //Complete on the rootScope 
    rootScope.Complete(); 

}

您可以找到有关TransactionScopes更多的信息,是如何工作的嵌套:MSDN

如果是这样的话,你可以通过正确嵌套的transactionscopes,例如解决您的问题,...在MSDN

我希望这个答案可以帮助未来的人。

如果分布式事务处理协调器服务未启动,实体框架无法连接到数据库。 打开并启动分布式事务处理协调

服务 - >分布式事务协调器