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

C# ADO实体框架是否支持非DTC事务?一个EntityContext和一个TransactionScope内的多个查询导致DTC升级,c#,entity-framework,transactions,transactionscope,msdtc,C#,Entity Framework,Transactions,Transactionscope,Msdtc,我有一个使用实体框架的web应用程序——我们利用TransactionScope类来提供环境事务 有没有办法告诉EF使用标准T-SQL事务而不是DTC事务?我们经常在一个EntityContext和一个TransactionScope实例中对不同的表进行大量查询,但是这似乎总是将事务提升到DTC 我把一个简短的例子放在一起,见下文。对单个表的查询正确地启动了一个T-SQL事务,并且处于连接SPID 54上 然后对ContactUs表进行查询,EF在另一个连接(SPID 53)上执行此操作,该连接

我有一个使用实体框架的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();
    }
}

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


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

您没有提到,但听起来您正在使用SQL Server 2005。在SQL Server 2005下,如果在TransactionScope内打开了多个连接,则事务将被删除。不管它是否是同一个数据库和同一个ConnectionString,它仍然会得到提升

这不是实体框架的“问题”,而是System.Transactions的现有行为。常规ADO.NET也存在此问题。在过去,我使用过Enterprise Library,它在封面下维护参与事务的连接列表,如果您在事务中尝试检索新连接,它将返回您已经打开并参与事务的连接

如果使用SQLServer2008,则行为会得到改进,以便

  • 在连接字符串上设置登记=false,以避免事务自动登记

  • 手动将连接登记为事务作用域中的参与者


  • 我在ASP.NET成员系统中使用实体框架时遇到了DTC升级问题,因为两者使用不同的连接字符串。在会员系统的连接字符串中设置“Enlist=false”为我解决了问题。

    我们遇到了相同的问题,但短期内无法升级。因此,我们对代码进行了编程,以显式地打开连接(StoreConnection)。这样可以避免事务升级。因为ObjectContext不会多次打开/关闭连接。