How to run two Entity Framework Contexts inside TransactionScope without MSDTC?

前端 未结 3 984
無奈伤痛
無奈伤痛 2021-02-07 09:39

This problem is not readily reproducible in a simple example here but was wondering if anyone has any experience and tips, here is the issue:

  • using Entity
相关标签:
3条回答
  • 2021-02-07 10:24

    I think that what you need to do is to force your contexts to share single database connection. You will be able then to perform these two operations against two different contexts in single transaction. You can achieve this by passing one EntityConnection object to both of your context's constructors. Of course this approach will require you to pass this object to methods which update DB.

    I have recently blogged about creating database context scope which will make using multiple EF contexts and transactions easier.

    0 讨论(0)
  • 2021-02-07 10:30

    Well, the problem is quite easy.

    If you are using sql server 2008 you should not have that problem because you have promotable transaction, and as .NET knows that you are using the same persistence store (the database) it wont promote it to DTC and commit it as local. look into promotable transaction with sql server 2008.

    As far as I know Oracle is working in its driver to support promotable transactions, but I do not know the state, MS oracle driver does not support it. http://www.oracle.com/technology/tech/windows/odpnet/col/odp.net_11.1.0.7.20_twp.pdf

    If you are using a driver that do not support promotable transactions it is impossible for .NET to use local transaction doing two connections. You should change your architecture or convince the database admin for installing MSDTC.

    0 讨论(0)
  • 2021-02-07 10:32

    I had a similar problem with SQL 2008, Entity Framework.

    I had two frameworks defined (EF1, and EF2) but using identical connection strings to a sql 2008 database.

    I got the MSDTC error above, when using nested "usings" across both. eg the code was like this:

    using (TransactionScope dbContext = new TransactionScope())
    {
         using (EF1 context = new EF1())
         {
             // do some EF1 db call
             using (EF2 context2 = new EF2())
             {
                  // do some EF2 db call
              }
          }
          dbContext.Complete();
    }
    

    It wasnt as simple as this, because it was split across several methods, but this was the basic structure of "usings".

    The fix was to only open one using at a time. No MTDSC error, No need to open distributed transactions on db.

    using (TransactionScope dbContext = new TransactionScope())
    {
         using (EF1 context = new EF1())
         {
             // do some EF1 db call
    
          }
         using (EF2 context2 = new EF2())
         {
                  // do some EF2 db call
         }
         dbContext.Complete();
    }
    
    0 讨论(0)
提交回复
热议问题