Problem with Transactional attribute in the factory method

Problem with Transactional attribute in the factory method

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


oleg posted on Wednesday, March 14, 2012

Hi everyone.

I have a problem.

My business class TemplateEdit has a method:

public static void DeleteTemplate(string id)

{

DataPortal.Delete<TemplateEdit>(id);

}

Factory class has a method:

[RunLocal]

[Transactional(TransactionalTypes.TransactionScope)]

public void Delete(string id)

{			
using (ConnectionManager<FbConnection> trx = ConnectionManager<FbConnection>.GetManager("DatabaseName"))
using (FbCommand cmd = trx.Connection.CreateCommand())
{			
	// do work		
}			
}

I get error: "There is no active TransactionScope to enlist transactions."

Version of CSLA: 4.1.0.0

There are no problems with other factory methods withTransactional attribute.

May be the problem in a static method?

Thanks for your help.

 

JonnyBee replied on Thursday, March 15, 2012

Hi Oleg,

Yes, this is a bug in Csla.Server.DataPortal. Good catch.

Added to Bugtracker: http://www.lhotka.net/cslabugs/edit_bug.aspx?id=1033

JonnyBee replied on Thursday, March 15, 2012

This code will fix the problem in Csla 4.x: 

Csla.Server.DataPortal.cs

        public DataPortalResult Delete(Type objectType, object criteria, DataPortalContext context)
        {
          try
          {
            SetContext(context);
 
            Authorize(new AuthorizeRequest(objectType, criteria, DataPortalOperations.Delete));
 
            DataPortalResult result;
            DataPortalMethodInfo method;
            var factoryInfo = ObjectFactoryAttribute.GetObjectFactoryAttribute(objectType);
            if (factoryInfo != null)
            {
              var factoryType = FactoryDataPortal.FactoryLoader.GetFactoryType(factoryInfo.FactoryTypeName);
              string methodName = factoryInfo.DeleteMethodName;
              method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, methodName, criteria);
            }
            else
            {
              method = DataPortalMethodCache.GetMethodInfo(objectType, "DataPortal_Delete", criteria);
            }
 
            IDataPortalServer portal;
            switch (method.TransactionalType)
            {
#if !MONO
              case TransactionalTypes.EnterpriseServices:
                portal = new ServicedDataPortal();
                try
                {
                  result = portal.Delete(objectType, criteria, context);
                }
                finally
                {
                  ((ServicedDataPortal)portal).Dispose();
                }
                break;
#endif
              case TransactionalTypes.TransactionScope:
                portal = new TransactionalDataPortal();
                result = portal.Delete(objectType, criteria, context);
                break;
              default:
                portal = new DataPortalSelector();
                result = portal.Delete(objectType, criteria, context);
                break;
            }
            return result;
          }
          catch (Csla.Server.DataPortalException ex)
          {
            Exception tmp = ex;
            throw;
          }
          catch (Exception ex)
          {
            throw new DataPortalException(
                "DataPortal.Delete " + Resources.FailedOnServer,
                new DataPortalExceptionHandler().InspectException(objectType, criteria, "DataPortal.Delete", ex),
                new DataPortalResult());
          }
          finally
          {
            ClearContext(context);
          }
        }

JonnyBee replied on Thursday, March 15, 2012

Issue is fixed in branches/v4-3-x and trunk.

Copyright (c) Marimer LLC