Csla.Data.DbContextManager Entity 5 Transactions Distributed Transaction Coordinator

Csla.Data.DbContextManager Entity 5 Transactions Distributed Transaction Coordinator

Old forum URL: forums.lhotka.net/forums/t/12119.aspx


aramka posted on Friday, August 16, 2013

Have there been any instances found where the DbContextManager opens a second connection? I have one client where im getting the exception

An error has occurred. Csla.DataPortalException: DataPortal.Update failed (The underlying provider failed on Open.) ---> Csla.Reflection.CallMethodException: EditableCategory.DataPortal_Update method call failed ---> System.Data.EntityException: The underlying provider failed on Open. ---> System.Transactions.TransactionManagerCommunicationException: Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool. ---> System.Runtime.InteropServices.COMException: The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024)


It looks like the DTC is being used, but I have take care to make sure all database updates, deletes, inserts occur within a using block like below
using (var cntx = DbContextManager<DataContext>.GetManager())
{
}


Also, in my dev environment I dont get this exception when running the same code and the DTC service is definitely disabled.


Also, we have another client who doesnt have the DTC service enabled and they do not get this error.
I understand that the DbContextManager is most likely solid in that it does what it says, but just thought I post here to see if maybe there was a bug or if anyone else has found a similar issue.

 

I've posted the code in this question

http://stackoverflow.com/questions/18278994/transaction-escalated-to-dtc-no-multiple-connections


Any help is greatly appreciated.


Thanks.










JonnyBee replied on Friday, August 16, 2013

Hi,

When you have more than 1 connection within the transaction it is automatically upgraded to use DTC.

It _might_ be a treading issue if your code runs on more than one thread as the DbContextManager is stored in a slot on the "current" thread.
Or the context gets out of scope and you autmatically create a new one with a new connection. You should make sure to have

using (var cntx = DbContextManager<DataContext>.GetManager())

in your DataPortal_XXZ methods and make sure that all updates occur with this scope.

 

aramka replied on Friday, August 16, 2013

Thanks for your help.

Im aware of the escalation process for transactions and I pretty sure I have one connection open. Here is my code

 

protected override void DataPortal_Update()
    {
        using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, System.Transactions.TransactionManager.MaximumTimeout))
        {
            //get the dal manager he knows which dal implementation to use
            using (var dalMgr = DataAccess.BusinessObjectsDalFactory.GetManager())
            {
                //get the category dal implementation
                var ecDal = dalMgr.GetProvider<DataAccess.BusinessObjectDalInterfaces.ICategoryDAL>();

                //assume all the data is good at this point so use bypassproperty checks
                using (BypassPropertyChecks)
                {
                    var catData = new Models.Category { CategoryId = CategoryId, CategoryName = CategoryName, LastChanged = TimeStamp };

                    ecDal.UpdateCategory(catData);

                    TimeStamp = catData.LastChanged;
                }
            }

            ts.Complete();
        }

        base.DataPortal_Update();
    }

public class DalManager : Core.Sebring.DataAccess.IBusinessObjectsDalManager {private static string _typeMask = typeof(DalManager).FullName.Replace("DalManager", @"{0}");

public T GetProvider<T>() where T : class
{
  var typeName = string.Format(_typeMask, typeof(T).Name.Substring(1));
  var type = Type.GetType(typeName);
  if (type != null)
    return Activator.CreateInstance(type) as T;
  else
    throw new NotImplementedException(typeName);
}

public Csla.Data.DbContextManager<DataContext> ConnectionManager { get; private set; }

public DalManager()
{
    ConnectionManager = Csla.Data.DbContextManager<DataContext>.GetManager();
}

public void Dispose()
{
  ConnectionManager.Dispose();
  ConnectionManager = null;
}


public void UpdateDataBase()
{
    DatabaseUpgrader.PerformUpgrade();
}
}

 public void UpdateCategory(Models.Category catData)
    {
        if (catData == null) return;
        using (var cntx = DbContextManager<DataContext>.GetManager())
        {
            var cat = cntx.DbContext.Set<Category>().FirstOrDefault(c => c.CategoryId == catData.CategoryId);

            if (cat == null) return;

            if (!cat.LastChanged.Matches(catData.LastChanged))
                throw new ConcurrencyException(cat.GetType().ToString());

            cat.CategoryName = catData.CategoryName;
            //cntx.DbContext.ChangeTracker.DetectChanges();
            cntx.DbContext.Entry<Category>(cat).State = System.Data.EntityState.Modified;
            cntx.DbContext.SaveChanges();
            catData.LastChanged = cat.LastChanged;
        }

    }

 

 

aramka replied on Tuesday, August 20, 2013

The problem turned out to be an issue with sql server 2005 and EF5. You can find more information here

http://stackoverflow.com/questions/18322218/ef-5-connection-management

And here

 

http://stackoverflow.com/questions/18278994/transaction-escalated-to-dtc-no-multiple-connections

Copyright (c) Marimer LLC