Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't TransactionScope work with Entity Framework?

People also ask

Does TransactionScope work with Entity Framework?

Entity Framework is already operating within a TransactionScope. The connection object in the transaction passed is null. That is, the transaction is not associated with a connection – usually this is a sign that that transaction has already completed.

Why you shouldn't use Entity Framework with transactions?

You can be sure that everything will be saved or every change will be discarded (Atomicity). By using transactions in EntityFramework, you change that behavior and force every CRUD operation during a transaction scope to be executed in serializable isolation mode which is the highest and most blocking type.

When should you not use Entity Framework?

One of the biggest reasons not to use Entity Framework Core is that your application needs the fastest possible data access. Some applications do a lot of heavy data operations with very high-performance demands, but usually business applications don't have that high of a performance demand.

How do I set isolation level in Entity Framework?

We can set Isolation Level using the ExecuteStoreCommand method of the context. It would affect generated LINQ to Entity queries. DBContext or Object context also supports explicitly setting the transaction on the context. Using transaction scope we can set transaction Isolation Level for current transaction.


Your MS-DTC (Distributed transaction co-ordinator) is not working properly for some reason. MS-DTC is used to co-ordinate the results of transactions across multiple heterogeneous resources, including multiple sql connections.

Take a look at this link for more info on what is happening.

Basically if you make sure your MS-DTC is running and working properly you should have no problems with using 2 ADO.NET connections - whether they are entity framework connections or any other type.


You can avoid using a distributed transaction by managing your own EntityConnection and passing this EntityConnection to your ObjectContext. Otherwise check out these.

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=580828&SiteID=1&mode=1 http://forums.microsoft.com/msdn/showpost.aspx?postid=113669&siteid=1&sb=0&d=1&at=7&ft=11&tf=0&pageid=1

EntityConnection conn = new EntityConnection(ConnectionString);

using (TransactionScope ts = new TransactionScope())
{
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn))
    {
            var v = (from s in o.Advertiser select s).First();
            v.AcceptableLength = 1;
    }

    //-> By commenting out this section, it works
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn))
    {
        //Exception on this next line
        var v = (from s1 in o.Advertiser select s1).First();
                v.AcceptableLength = 1;
    }
    //->

    ts.Complete();
}

Add C:\Windows\msdtc.exe to the firewall exceptions on both the firewall and server. I spent ages monkeying around opening specific port numbers and ranges to no avail before I did this.


I'm going to stick this here because I spent 3 hours with a colleague yesterday debugging this issue. Every single answer surrounding this says that this is always a firewall issue; however in our case it wasn't. Hopefully this will spare someone else the pain.

The situation that we have is that we are currently in the process of migrating to the Entity Framework. That means that we have parts of the code where inside a single transaction connections are opened both directly using a new SqlConnection(connectionString).Open() and indirectly by using an EF data context.

This has been working fine in our application for a while, but when we started to retrospectively go and put tests around the code that worked in production, the code executed from the test runner kept throwing this error the first time the EF object tried to connect to the database after a direct connection had been made in the same transaction.

The cause of the bug eventually turned out to be that if you do not supply an Application Name= argument to your connection string, the Entity Framework adds one by default (something like EntityFrameworkMUF). This means that you have two distinct connections in your connection pool:

  1. The one that you open manually with no Application Name= argument
  2. An automatically generated one suffixed Application Name=EntityFrameworkMUF

and it is not possible to open two distinct connections inside a single transaction. The production code specified an application name; hence it worked; the test code did not. Specifying the Application Name= argument fixed the bug for us.