1 2 3 Previous Next 33 Replies Latest reply on Jul 30, 2008 12:16 PM by Brice Ruth

    No active JTA Tx?? Spring + JTA Tx rollback on JBossTS

    Brice Ruth Novice

      We are seeing a strange error while using JTA in JBoss 4.3 EAP. We have a POJO configured with the Spring Tx interceptor. Before the interceptor is invoked, a Tx is associated with the thread and Spring's interceptor happily works with it (propagation required). Successful execution allows everything to proceed and the Tx is committed successfully.

      However, when an exception occurs, for some reason, things go horribly wrong.

      Here's the output we see in the log, mostly from Spring as far as we can tell:

      16:12:48,061 INFO [STDOUT] 16:12:48,061 DEBUG [TransactionInterceptor] Completing transaction for [...controller.ITaskController.completeTasks] after exception: org.jbpm.JbpmException: [snip]
      16:12:52,545 INFO [STDOUT] 16:12:52,545 DEBUG [RuleBasedTransactionAttribute] Applying rules to determine whether transaction should rollback on org.jbpm.JbpmException: [snip]
      16:12:52,561 INFO [STDOUT] 16:12:52,561 DEBUG [RuleBasedTransactionAttribute] Winning rollback rule is: null
      16:12:52,561 INFO [STDOUT] 16:12:52,561 DEBUG [RuleBasedTransactionAttribute] No relevant rollback rule found: applying superclass default
      16:13:11,249 INFO [STDOUT] 16:13:11,249 DEBUG [JtaTransactionManager] Triggering beforeCompletion synchronization
      16:13:11,249 INFO [STDOUT] 16:13:11,249 DEBUG [TransactionSynchronizationManager] Removed value [org.springframework.orm.hibernate3.SessionHolder@151f2a9] for key [org.hibernate.impl.SessionFactoryImpl@6a641d] from thread [http-127.0.0.3-8080-2]
      16:13:11,265 INFO [STDOUT] 16:13:11,249 DEBUG [TransactionSynchronizationManager] Removed value [org.springframework.jdbc.datasource.ConnectionHolder@79c26] for key [org.jboss.resource.adapter.jdbc.WrapperDataSource@b6dff] from thread [http-127.0.0.3-8080-2]
      16:13:11,265 INFO [STDOUT] 16:13:11,265 DEBUG [JtaTransactionManager] Participating transaction failed - marking existing transaction as rollback-only
      16:13:11,265 INFO [STDOUT] 16:13:11,265 DEBUG [JtaTransactionManager] Setting JTA transaction rollback-only
      16:13:11,265 INFO [STDOUT] 16:13:11,265 DEBUG [JtaTransactionManager] Registering after-completion synchronization with existing JTA transaction
      16:13:11,280 INFO [STDOUT] 16:13:11,280 DEBUG [TransactionSynchronizationManager] Clearing transaction synchronization
      16:13:32,828 INFO [STDOUT] 16:13:32,812 ERROR [TransactionInterceptor] Application exception overridden by rollback exception
      


      The last line indicates a rollback exception. That exception is as follows.

      org.springframework.transaction.NoTransactionException: No active JTA transaction
       at org.springframework.transaction.jta.JtaTransactionManager.registerAfterCompletionWithExistingTransaction(JtaTransactionManager.java:903)
       at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCompletion(AbstractPlatformTransactionManager.java:885)
       at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:782)
       at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:730)
       at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:332)
       at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:111)
       at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
       at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
       at $Proxy70.completeTasks(Unknown Source)
      


      So, apparently somewhere in the process of handling the exception, the JTA transaction is no longer associated with the thread?! We are a bit at a loss here ... the level of the application where this is occuring shouldn't be manipulating if the JTA transaction (parent) is associated with the thread or not ... since it is only participating, it didn't create the transaction. So how can it be disassociated?

      Any help on how to get to the bottom of this would be greatly appreciated. For example, where could I set a breakpoint to figure out what is invoking the presumed suspend() on the parent transaction, which would disassociate it from the thread?

      Thanks,
      Brice

        • 1. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
          Brice Ruth Novice

          OK, I've stepped through some code that I won't pretend to understand well. But, what I'm seeing is that the Spring interceptor code sees that it is participating in an external transaction, and so it tries to register 'afterCompletion' synchronizations with the JTA TxM.

          The JTA TxM, however, appears to not allow synchronizations to be registered in the state that the Tx is in when Spring tries to register them. This happens in the call stack of Spring's doRollback, so it seems like Spring is trying to register the necessary pieces to clean up, after the Tx is completed (rolled back).

          This is leading me to think that I have something configured wrong between the JBoss TxM in JBoss 4.3 and Spring (2.0.8), or Spring is trying to do something 'illegal' when the Tx is in a rollbackOnly state. The 'state' in TransactionImple#registerSynchronizationImple() is 3. Not sure what that means ... ?

          • 2. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
            Andrew Dinn Master

             


            This is leading me to think that I have something configured wrong between the JBoss TxM in JBoss 4.3 and Spring (2.0.8), or Spring is trying to do something 'illegal' when the Tx is in a rollbackOnly state. The 'state' in TransactionImple#registerSynchronizationImple() is 3. Not sure what that means ... ?


            Hmm, yes, that's state ABORT_ONLY. Looking at the exception stack trace Spring appears to rely on adding a synchronization to the JTA transaction to do its cleanup when it detects that the transaction must be rolled back.

            The JBoss TM explicitly rejects attempts to add a synchronization if the transaction status is anything other than RUNNING. If you look at the JTA 1.1 spec it includes the following exception condition for registerSynchronization (page 36):


            Throws: RollbackException
            Thrown to indicate that the transaction has been marked for rollback only.


            So, nothing is configured wrong; it looks rather that Spring appears to be coded wrong.

            • 3. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
              Brice Ruth Novice

               

              "adinn" wrote:

              This is leading me to think that I have something configured wrong between the JBoss TxM in JBoss 4.3 and Spring (2.0.8), or Spring is trying to do something 'illegal' when the Tx is in a rollbackOnly state. The 'state' in TransactionImple#registerSynchronizationImple() is 3. Not sure what that means ... ?


              Hmm, yes, that's state ABORT_ONLY. Looking at the exception stack trace Spring appears to rely on adding a synchronization to the JTA transaction to do its cleanup when it detects that the transaction must be rolled back.

              The JBoss TM explicitly rejects attempts to add a synchronization if the transaction status is anything other than RUNNING. If you look at the JTA 1.1 spec it includes the following exception condition for registerSynchronization (page 36):


              Throws: RollbackException
              Thrown to indicate that the transaction has been marked for rollback only.


              So, nothing is configured wrong; it looks rather that Spring appears to be coded wrong.


              Oh joy. Now what?

              • 4. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                Brice Ruth Novice

                OK, found the following JIRA open in Spring:

                http://jira.springframework.org/browse/SPR-4107

                Supposedly fixed in 2.0.8, which is what we're using. This came from the following thread that I found:

                http://forum.springframework.org/showthread.php?t=27867&highlight=synchronization+jboss&page=2

                One thing mentioned here is that what you say with respect to the JTA spec is correct ... but apparently JBossTS isn't throwing a rollback exception, its throwin an illegal state exception. Wouldn't this be a violation of the JTA spec?

                Thanks,
                Brice

                • 5. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                  Brice Ruth Novice

                  Wow, not using 2.0.8 afterall, using 2.0.5. That actually makes me happy ... maybe this will be an easy fix ;-)

                  • 6. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                    Andrew Dinn Master

                     


                    One thing mentioned here is that what you say with respect to the JTA spec is correct ... but apparently JBossTS isn't throwing a rollback exception, its throwin an illegal state exception. Wouldn't this be a violation of the JTA spec?


                    Hmm, when diagnosing this I looked at the JTA TX implementation in trunk which I happen to have open in Idea. It is throwing a rollback exception in the case the TX is ABORT_ONLY or ABORTED. It throws an IllegalState exception if the TX is in any other state (with the obvious exception of RUNNING). In previous releases (e.g. 4.2.3.SP5 and before) the ABORT_ONLY case was subsumed under default processing so it generated IllegalState which is in violation of the spec. The Spring guys may have noted the error against these releases. The current correct behaviour is included in 4.3.GA which I believe you are using, no?


                    • 7. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                      Brice Ruth Novice

                       

                      "adinn" wrote:

                      One thing mentioned here is that what you say with respect to the JTA spec is correct ... but apparently JBossTS isn't throwing a rollback exception, its throwin an illegal state exception. Wouldn't this be a violation of the JTA spec?


                      Hmm, when diagnosing this I looked at the JTA TX implementation in trunk which I happen to have open in Idea. It is throwing a rollback exception in the case the TX is ABORT_ONLY or ABORTED. It throws an IllegalState exception if the TX is in any other state (with the obvious exception of RUNNING). In previous releases (e.g. 4.2.3.SP5 and before) the ABORT_ONLY case was subsumed under default processing so it generated IllegalState which is in violation of the spec. The Spring guys may have noted the error against these releases. The current <em>correct</em> behaviour is included in 4.3.GA which I believe you are using, no?


                      Ah, good to know. I believe that since this is in ArjunaCore, the code would still be 4.2.3_SP5 - that's what's in JBoss AS 4.3.0 EAP. We're running the XTS code from JBossTS 4.3.

                      • 8. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                        Brice Ruth Novice

                        OK, Spring 2.0.8 seems to handle the IllegalStateException that TS 4.2.3_SP5 throws in 4.3 EAP.

                        However, the bridge is now having a problem with it. With a little help, I can probably monkey patch this ...

                        08:58:37,204 INFO [STDOUT] 08:58:37,204 ERROR [JaxWSTransactionBridgeHandler] java.lang.IllegalStateException: Transaction not in state ACTIVE
                        


                        Here's a rough shot at the sequence of events.


                        1. Service is invoked
                        2. Incoming header processor detects no coordination context
                        3. Incoming header processor begins a wst UserTransaction instead of resuming one with the coordination context
                        4. Inbound Bridge handler starts the bridge, binding a top-level JTA Tx with the wst UserTransaction
                        5. Handler process ends, ServiceBean proxy is invoked, invoking the Spring Tx interceptor
                        6. Spring interceptor determines that a top-level JTA Tx is already bound to the Thread, participates
                        7. Service code is invoked, exception is thrown from app-code
                        8. FaultBridgeHandler is invoked, invokes handleFault() on JaxWSTransactionBridgeHandler
                        9. JaxWSTransactionBridgeHandler invokes suspendTransaction, disassociates top-level JTA Tx from Thread (I think)
                        10. Fault header context processor is invoked, determines that no remote coordination is present
                        11. Fault header context processor retrieves wst UserTransaction from thread, invokes rollback()
                        12. Top-level wst UserTransaction invokes rollback() on BridgeParticipantAT, which then throws the above exception, complaining that the top-level JTA Tx is not ACTIVE.


                          Boy, that's the first time I've spelled that all out. So ... seems like everything is OK, except that the BridgeParticipantAT maybe needs to do something else with the XATerminatorImple, if the state is ABORT_ONLY??


                        • 9. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                          Brice Ruth Novice

                          Correction:

                          Step #9 above doesn't complete successfully, this is where the IllegalStateException is thrown.

                          In InboundBridge, in getTransaction(), if the top-level Tx is not ACTIVE, it throws this. Is that valid? getTransaction() is being called from handleFault() -> suspendTransaction() -> stop() -> getTransaction(). Is it not valid to suspend a top-level JTA Tx that is marked ABORT_ONLY?

                          Thanks,
                          Brice

                          • 10. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                            Brice Ruth Novice

                            FYI, in JaxWSTransactionBridgeHandler, the IllegalStateException is swallowed ... that's probably not good?!

                            catch (Exception e)
                            {
                            log.error(e);
                            }

                            • 11. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                              Brice Ruth Novice

                              OK, riddle me this. If Spring attempts to register a ConnectionSynchronization, which has an afterCompletion() ... and the Transaction is in ABORT_ONLY, so it throws an IllegalStateException (or RollbackException) in JBossTS 4.3 ... what happens to calling that afterCompletion() on the ConnectionSynchronization. From what I can tell, this is where Spring will close() the javax.sql.Connection, which releases it back to the managed connection pool, right?

                              The reason I'm asking is that after I run a few transactions through my service (where I'm accounting for the IllegalStateException in InboundBridge and still suspending the ABORT_ONLY top-level Tx) - my service is unusable, I get the following exception.

                              No ManagedConnections available within configured blocking timeout ( 30000 [ms] ); - nested throwable: (javax.resource.ResourceException: No ManagedConnections available within configured blocking timeout ( 30000 [ms] ))
                              


                              Any ideas?

                              • 12. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                                Andrew Dinn Master

                                 


                                OK, riddle me this. If Spring attempts to register a ConnectionSynchronization, which has an afterCompletion() ... and the Transaction is in ABORT_ONLY, so it throws an IllegalStateException (or RollbackException) in JBossTS 4.3 ... what happens to calling that afterCompletion() on the ConnectionSynchronization. From what I can tell, this is where Spring will close() the javax.sql.Connection, which releases it back to the managed connection pool, right?


                                Not much of a riddle.

                                The JTA spec requires the Tx manager to throw a RollbackException.

                                So that's what we do.

                                So Spring is $%^&#ed

                                (at least, it is if you are correct that Spring is relying upon this mechanism :-)


                                • 13. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                                  Brice Ruth Novice

                                  Maybe I'm just confused ... doesn't *something* have to release the database connection back to the ManagedConnectionPool, and can't this only happen after the transaction has completed? Or is there something special between the JCA ManagedConnectionPool and the JTA transaction manager that handles this when the transaction is completed outside the scope of the application?

                                  • 14. Re: No active JTA Tx?? Spring + JTA Tx rollback on JBossTS
                                    Jonathan Halliday Master

                                    The JCA should return the connection to the pool on transaction termination. Having an app call close() on a connection handle does not necessarily put it back in the pool. The track-connection-by-tx setting plays a part too. Such matters are really better off being discussed in the JCA forum.

                                    1 2 3 Previous Next