Multiple database in one transaction in Entity Framework

.net asp.net c# entity-framework transactions

Question

I have created two different Contexts for two different databases in Entity Framework. Now I am trying to update these databases in single transaction. My code is like that:

public class LPO_BLL
{
    internal Context1 _context1 = null;
    internal Context2 _Context2 = null;

    public LPO_Detail_BLL(Context1 context1, Context2 context2)
    {
        _context1 = context1;
        _context2 = context2;
    }

    public void Insert(PM_LPO lpo, LPO_Transaction lpo_transaction)
    {
        using (TransactionScope transaction = new TransactionScope())
        {
            _context1.LPO.Add(lpo);
            _context1.SaveChanges();

            _context2.LPO_Transaction.Add(lpo_transaction);
            _context2.SaveChanges();  // I am getting error here...

            transaction.Complete();
        }
    }
}

And in UI project, I am calling this as:

LPO lpo = new LPO();
//setting properties of lpo

LPO_Transaction lpo_trans = new LPO_Transaction();
//setting properties of lpo_trans

Context1 _context1 = new Context1();
//Opening _context1 connection and etc

Context2 _context2 = new Context2();
//Opening _context2 connection and etc

LPO_BLL lpo_bll = new LPO_BLL(_context1, _context2);

lpo_bll.Insert(lpo,lpo_trans);

At the moment, I am getting error : The underlying provider failed on EnlistTransaction

After searching over the internet for last 3 hours and trying different hit and trial methods, I decided to put this on SO. So far, i have found these two links to little bit closer:

http://social.msdn.microsoft.com/Forums/en-US/3ccac6f7-6513-4c87-828a-00e0b88285bc/the-underlying-provider-failed-on-enlisttransaction?forum=adodotnetentityframework

TransactionScope - The underlying provider failed on EnlistTransaction. MSDTC being aborted

1
2
5/23/2017 12:10:39 PM

Accepted Answer

Not all DB providers support distributed transactions.

Using transaction scopes will try to enlist the DB transaction in a distributed transacation managed by MSDTC. If your provider doesn't support this, it will fail.

SQL Server and Oracle providers support distributed transactions. But many other EF providers don't.

If your DB provider doesn'd support this, you'll have to use a different one or give up using transactions.

Provided you're using SQL Server 2005, it should be working, but:

  • MSDTC service must be running (look for it in Services, in the Control Panel).
  • the connection strings must be adequate for MSDTC to work

Look at this SO Q&A: confusion about transactions and msdtc.

NOTE: The name of the service is MSDTC. So you can run net start msdtc or net stop msdtc. If you're looking for it in the control panel, you'll find a descriptive name like "Distributed Transaction Coordinator" or a localized name like "Coordinador de transacciones distribuidas". Oddly enough, there is no way to show the name column in the control panel list of local services.

3
5/23/2017 11:54:54 AM

Popular Answer

You have to use ObjectContext in you DbContext in order to use SaveChanges with parameter:

public class EntityDBContext: DbContext, IObjectContextAdapter
{
    ObjectContext IObjectContextAdapter.ObjectContext {
        get { 
           return (this as IObjectContextAdapter).ObjectContext;
        }
    }
}

and then in your Insert method, use:

public void Insert(PM_LPO lpo, LPO_Transaction lpo_transaction)
{
    using (TransactionScope transaction = new TransactionScope())
    {

         context1.ObjectContext.SaveChanges(false);
         context2.ObjectContext.SaveChanges(false);

         _context1.LPO.Add(lpo);
         _context2.LPO_Transaction.Add(lpo_transaction);       

         transaction.Complete();

         context1.ObjectContext.AcceptAllChanges();
         context2.ObjectContext.AcceptAllChanges();

    }
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow