ADO实体框架是否支持非DTC交易?一个EntityContext和一个TransactionScope内的多个查询导致DTC升级

时间:2010-01-08 09:39:21

标签: c# entity-framework transactions transactionscope msdtc

我有一个使用Entity Framework的Web应用程序 - 我们使用TransactionScope类来提供环境事务。

有没有办法告诉EF使用标准T-SQL交易优先于DTC交易?我们经常对一个EntityContext和一个TransactionScope实例中的不同表进行大量查询,但这似乎总是将事务提升为DTC

我举了一个简短的例子,见下文。对单个表的查询正确地启动了T-SQL事务,并且在连接SPID 54上 然后对ContactUs表进行查询,并且EF在不同的连接(SPID 53)上执行此操作,该连接具有将事务提升为DTC事务的效果。**

using (MyEntities DB = new MyEntities())
{
    using (TransactionScope t = new TransactionScope())
    {
        DB.Individual.First().EmailAddress = "bob" + DateTime.Now.Second.ToString() + "@bob.com"; // done on connection 54
        DB.ContactUs.First(); // done on connection 53 thus promoting the transaction!!
        DB.SaveChanges();
        t.Complete();
    }
}

4 个答案:

答案 0 :(得分:7)

  1. 在连接字符串上设置 Enlist = false ,以避免在事务中自动登记。

  2. 手动登记连接作为事务范围的参与者。 (http://msdn.microsoft.com/en-us/library/ms172153%28v=VS.80%29.aspx)

答案 1 :(得分:4)

您没有提及,但听起来您正在使用SQL Server 2005.在SQL Server 2005下,如果在TransactionScope中打开了多个连接,则事务将escalate from a lightweight transaction to a distributed transaction。如果它是相同的数据库和相同的ConnectionString并不重要 - 它仍然会被提升。

这不是Entity Framework的“问题”,因为它是System.Transactions的现有行为。普通的ADO.NET也存在这个问题。在过去,我使用了Enterprise Library,其中包含了参与事务的连接列表,如果您在事务中尝试检索新连接,它将返回已经打开并参与您的连接的连接。事务。

如果您使用SQL Server 2008,则行为会得到改进,以便transactions are not promoted when opening multiple connections to the same database

答案 2 :(得分:1)

导致使用分布式交易的不是实体框架;相反,它是TransactionScope。 EF将使用“正常”事务来包装在对SaveChanges()的单个调用的上下文中执行的所有SQL语句。在您给出的示例中,您只需拨打一次SaveChanges。因此,您根本不需要使用TransactionScope来自动应用更改。

我不知道如何使TransactionScope使用非分布式事务,但我有理由相信它不是实体框架。

答案 3 :(得分:0)

我正在使用带有ASP.NET成员资格系统的Entity Framework来解决DTC升级问题,因为两者使用不同的连接字符串。在会员系统的连接字符串中设置“Enlist = false”为我解决了问题。