- 
                Notifications
    You must be signed in to change notification settings 
- Fork 38.8k
Description
Christopher G. Stach II opened SPR-3052 and commented
I don't have a test case for this, but I wish I did. Luckily, it's easy to replicate. Maybe you have some ideas on making one more quickly than I could. :)
We are accepting messages from ActiveMQ 4.1.0's via its ResourceAdapter with Jencks 2.0. Hibernate 3.2.0 is involved for persistence. All of this is running inside of Resin 3.0.22, which acts as the JCA pool for AMQ and the database pool, so it's the transaction manager. XA transactions and JtaTransactionManager are being used.
Steps involved:
- Accept a message from AMQ with an existing Resin UserTransaction via Jencks
- Involve Hibernate and MySQL
- TransactionInterceptor triggers a Hibernate flush, which deadlocks and generates a RuntimeException (SpringSessionSynchronization line 126)
- The exception is caught at AbstractPlatformTransactionManager line 678, and a rollback is attempted at line 682
- AbstractPlatformTransactionManager line 791 skips over doRollback because the transaction is not new (AbstractPlatformTransactionManager lines 327 to 441), it existed starting when the JCA connector accepted the queued message (JtaTransactionManager.doRollback would have marked Resin's UserTransaction for rollback)
- Execution continues until Jencks' XAEndpoint line 101, which checks Resin's UserTransaction's status and calls commit instead of rollback
Stack trace when the deadlock happens:
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at
org.springframework.orm.hibernate3.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:126)
at
org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:48)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:821)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:637)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:624)
at
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:307)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
at
com.xxx.interceptor.XxxInterceptor.invoke(DistributingInterceptor.java:152)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:210)
at $Proxy70.runMethods(Unknown Source)
at sun.reflect.GeneratedMethodAccessor751.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:270)
at
com.xxx.jms.JmsMessageListenerService.onMessage(JmsMessageListenerService.java:124)
at org.jencks.XAEndpoint.onMessage(XAEndpoint.java:129)
at
org.apache.activemq.ra.MessageEndpointProxy$MessageEndpointAlive.onMessage(MessageEndpointProxy.java:121)
at
org.apache.activemq.ra.MessageEndpointProxy.onMessage(MessageEndpointProxy.java:61)
at org.apache.activemq.ActiveMQSession.run(ActiveMQSession.java:695)
at
org.apache.activemq.ra.ServerSessionImpl.run(ServerSessionImpl.java:165)
at com.caucho.jca.WorkThread.run(WorkThread.java:99)
at com.caucho.util.ThreadPool.runTasks(ThreadPool.java:520)
at com.caucho.util.ThreadPool.run(ThreadPool.java:442)
at java.lang.Thread.run(Thread.java:619)
Affects: 1.2.8, 2.0.2
Backported to: 1.2.9