Uploaded image for project: 'Spring.NET'
  1. Spring.NET
  2. SPRNET-1434

Using the HibernateTxScopeTransactionManager, Creating a New Spring Transaction While in an Existing Transaction Scope Created By A WCF Service Throws An Error

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 1.3.1
    • Fix Version/s: FUTURES
    • Component/s: Spring-NET-NH
    • Labels:
      None

      Description

      If there's an existing TX Scope transaction, such as one created at the entry point of a WCF service with OperationBehavior transaction attributes, entering a method with Spring Transactional Attributes with TransactionScope=RequiresNew throws an error.

      In the GetTransaction() method in the AbstractPlatformTransactionManager class, the IsExistingTransaction() method returns true, since the implementation of the IsExistingTransaction() method implementation in the HibernateTxScopeTransactionManager looks in the TxScopeAdapter for an existing transaction, which is determined by whether or not System.Transaction.Transaction.Current is null. Since a transaction was started by the OperationBehavior attribute on the WCF service, System.Transaction.Transaction.Current is not null.

      The execution logic then goes into the HandleExistingTransaction() method in the AbstractPlatformTransactionManager class. Since the method it's entering is attributed with Spring Transaction attributes with TransactionScope=RequiresNew, the existing transaction created by the WCF service should be suspended.

      However, the following error is thrown in the DoSuspend() method in the HibernateTxScopeTransactionManager class:

      Message: No value for key [NHibernate.Impl.SessionFactoryImpl] bound to thread [7]
      StackTrace: at Spring.Transaction.Support.TransactionSynchronizationManager.UnbindResource(Object key)
      at Spring.Data.NHibernate.HibernateTxScopeTransactionManager.DoSuspend(Object transaction)
      at Spring.Transaction.Support.AbstractPlatformTransactionManager.Suspend(Object transaction)
      at Spring.Transaction.Support.AbstractPlatformTransactionManager.HandleExistingTransaction(ITransactionDefinition definition, Object transaction, Boolean debugEnabled)
      at Spring.Transaction.Support.AbstractPlatformTransactionManager.GetTransaction(ITransactionDefinition definition)
      at Spring.Transaction.Interceptor.TransactionAspectSupport.CreateTransactionIfNecessary(ITransactionAttribute sourceAttr, String joinpointIdentification)
      at Spring.Transaction.Interceptor.TransactionInterceptor.Invoke(IMethodInvocation invocation)
      at InheritanceAopProxy_ffdf022ef7c7422184ff3117874fb207.UpdateItemProcessingDate(Guid queueItemId, Nullable`1 processingDate)

      In the DoSuspend() method, the execution logic tries to Unbind the NHibernate session and the DB Connection holder from the Thread Context and place it in a Suspended Resource data structure. However, since the initial transaction was created by the WCF service, the NHibernate session and DB connection were never bound to the Thread Context dictionary. Therefore, the above exception occurs.

      Would it be correct to check to see if the resource exists before unbinding to avoid the exception?

        Attachments

          Activity

            People

            • Assignee:
              sbohlen Steve Bohlen
              Reporter:
              mpchou Marcus Chou
            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: