Does ADO Entity Framework support non DTC transactions? Multiple queries inside one EntityContext and one TransactionScope is causing DTC promotion
Asked Answered
E

4

3

I have a web application that uses the Entity Framework - we make use of the TransactionScope class to provide ambient transactions.

Is there any way to tell EF to use a standard T-SQL transaction in preference to DTC transaction? Quite often we make a number of queries to different tables inside one EntityContext and one TransactionScope instance, however this seems to always promote the transaction to DTC

I have put a short example together, see below. The query to the individual table correctly starts a T-SQL transaction and was on connection SPID 54 Then the query to the ContactUs table is made and EF does this on a different connection (SPID 53) which has the knock on effect of promoting the transaction to a DTC transaction.**

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();
    }
}
Escaut answered 8/1, 2010 at 9:39 Comment(0)
C
7
  1. Set Enlist=false on connection string to avoid auto enlistment on transaction.

  2. Manually enlist connection as participants in transaction scope. (http://msdn.microsoft.com/en-us/library/ms172153%28v=VS.80%29.aspx)

Chrisoula answered 4/8, 2010 at 17:44 Comment(0)
I
4

You didn't mention, but it sounds like you are using SQL Server 2005. Under SQL Server 2005, if more than one connection is opened inside a TransactionScope then the transaction will escalate from a lightweight transaction to a distributed transaction. It doesn't matter if it is the same database and the same ConnectionString -- it still gets promoted.

This isn't an "issue" with Entity Framework as much as it is an existing behavior with System.Transactions. The issue exists with regular ADO.NET as well. In the past I have used Enterprise Library which under the covers maintains a list of connections that are participating in transactions and if you attempt to retrieve a new connection while in a transaction, it will return you the connection that is already open and participating in your transaction.

If you use SQL Server 2008, then the behavior is improved so that transactions are not promoted when opening multiple connections to the same database.

Impoverish answered 8/1, 2010 at 23:15 Comment(1)
We experienced the same issue but upgrading is not possible in the short term. So we programmed the code to open the connection (StoreConnection) explicitly. This way you avoid Transaction escalation. Since the ObjectContext won't open/close the connection multiple times.Fuzz
J
1

It is not the Entity Framework which is causing use of distributed transactions; rather, it is TransactionScope. The EF will use a "normal" transaction to wrap up all SQL statements executed in the context of a single call to SaveChanges(). In the example you give, you have only one call to SaveChanges. Therefore, you would not need to use TransactionScope at all to have your changes applied atomically.

I do not know how to make TransactionScope use non-distributed transactions, but I'm reasonably confident that it is not the Entity Framework which is doing this.

Jodijodie answered 8/1, 2010 at 13:0 Comment(0)
R
0

I was hitting DTC escalation issues using Entity Framework with the ASP.NET membership system as the two use different connection strings. Setting "Enlist=false" in the membership system's connection string solved the problem for me.

Recession answered 27/9, 2012 at 12:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.