为什么在stage3CommitProcessing期间事务回滚?

发布于 2024-11-29 01:25:41 字数 11521 浏览 2 评论 0原文

在两个 Websphere 节点中运行的 Java 程序中,以下竞争场景发生在由 Websphere Transaction Manager 管理的分布式事务中。该事务跨越 JMS (Websphere-MQ) 事务源和数据库 (Oracle) 事务源。我想了解

  • 为什么会发生此异常(线程 2 中的异常,步骤 B6)? 我预计不会发生任何问题。线程 2 仅在确保 T1 在事务 TX2 中锁定后才继续执行,因此线程 1 自然会等待 T1 表锁(在事务 TX1 内)释放。我想知道的是为什么线程2会遇到stage3CommitProcessing异常?我如何才能获得有关它的更多详细信息,因为异常没有提供任何有关它的信息?
  • 如何调试这种与交易相关的竞赛场景?我知道这可能很难重现。但我认为可能有一些与 Websphere 相关的日志,我可以启用这些日志来查看是什么导致在 stage3 期间提交失败?如果有人能指出我那个方向,那就太好了。
  • 如何避免/解决?

线程 1(在 Websphere 节点 1 中运行)

A1: Start TX1
A2: Read messages (maximum of 1000 at a time) from Queue Q1
A3: LOCK TABLE T1 IN EXCLUSIVE MODE
        Got exception "ORA-02049": distributed transaction waiting for lock.  
Refer Log 1 for stack trace

线程 2(在 Websphere 节点 2 中运行)

B1: Start TX2
B2: Read messages (maximum of 1000 at a time) from Queue Q1
B3: LOCK TABLE T1 IN EXCLUSIVE MODE
B4: Batch execute
    MERGE INTO T1 the messages read
B5: Batch insert messages into T2
B6: Commit TX2
    Got JTA transaction unexpectedly rolled back (maybe due to a timeout). Refer Log 2 for stack trace.  This was while ***stage3CommitProcessing***.

日志 1:

org .springframework.jdbc.BadSqlGrammarException:StatementCallback;错误的 SQL 语法 [LOCK TABLE T1 IN EXCLUSIVE MODE];嵌套异常是 java.sql.SQLSyntaxErrorException: ORA-02049: timeout: 分布式事务等待锁

at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:94)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:406)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:518)
at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.update(SimpleJdbcTemplate.java:248)
at com.test.OracleTableLock.processMessage(OracleTableLock.java:52)
at sun.reflect.GeneratedMethodAccessor833.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy153.receiveMessage(Unknown Source)
at com.test.BatchProcessor.processMessage(BatchProcessor.java:343)
at sun.reflect.GeneratedMethodAccessor779.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy155.receiveMessage(Unknown Source)
at sun.reflect.GeneratedMethodAccessor778.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
at org.springframework.scheduling.support.MethodInvokingRunnable.run(MethodInvokingRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:453)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:329)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:162)
at org.springframework.scheduling.commonj.TimerManagerTaskScheduler$TimerScheduledFuture.timerExpired(TimerManagerTaskScheduler.java:112)
at com.ibm.ws.asynchbeans.timer.TimerImpl.callListenerMethod(TimerImpl.java:298)
at com.ibm.ws.asynchbeans.timer.GenericTimer.run(GenericTimer.java:216)
at com.ibm.ws.asynchbeans.J2EEContext$RunProxy.run(J2EEContext.java:264)
at java.security.AccessController.doPrivileged(AccessController.java:224)
at javax.security.auth.Subject.doAs(Subject.java:495)
at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:131)
at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:89)
at com.ibm.ws.asynchbeans.J2EEContext$DoAsProxy.run(J2EEContext.java:335)
at java.security.AccessController.doPrivileged(AccessController.java:251)
at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1146)
at com.ibm.ws.asynchbeans.timer.TimerImpl.runListenerAsCJWork(TimerImpl.java:425)
at com.ibm.ws.asynchbeans.am._Alarm.fireAlarm(_Alarm.java:333)
at com.ibm.ws.asynchbeans.am._Alarm.run(_Alarm.java:230)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1550)
Caused by: java.sql.SQLSyntaxErrorException: ORA-02049: timeout: distributed transaction waiting for lock

at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:91)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:206)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:413)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:1034)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:183)
at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:942)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1222)
at oracle.jdbc.driver.OracleStatement.executeUpdateInternal(OracleStatement.java:1706)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:1674)
at oracle.jdbc.driver.OracleStatementWrapper.executeUpdate(OracleStatementWrapper.java:275)
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.pmiExecuteUpdate(WSJdbcStatement.java:1683)
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.executeUpdate(WSJdbcStatement.java:1041)
at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:508)
at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:1)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:395)
... 50 more

日志 2:

org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException
    at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1012)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at com.test.BatchProcessor.processMessage(BatchProcessor.java:359)
    at sun.reflect.GeneratedMethodAccessor1541.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    at java.lang.reflect.Method.invoke(Method.java:600)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy204.receiveMessage(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor1540.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    at java.lang.reflect.Method.invoke(Method.java:600)
    at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
    at org.springframework.scheduling.support.MethodInvokingRunnable.run(MethodInvokingRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:453)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:329)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java)
    at org.springframework.scheduling.commonj.TimerManagerTaskScheduler$TimerScheduledFuture.timerExpired(TimerManagerTaskScheduler.java:112)
    at com.ibm.ws.asynchbeans.timer.TimerImpl.callListenerMethod(TimerImpl.java:298)
    at com.ibm.ws.asynchbeans.timer.GenericTimer.run(GenericTimer.java:216)
    at com.ibm.ws.asynchbeans.J2EEContext$RunProxy.run(J2EEContext.java:264)
    at java.security.AccessController.doPrivileged(AccessController.java:224)
    at javax.security.auth.Subject.doAs(Subject.java:495)
    at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:131)
    at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:89)
    at com.ibm.ws.asynchbeans.J2EEContext$DoAsProxy.run(J2EEContext.java:335)
    at java.security.AccessController.doPrivileged(AccessController.java:251)
    at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1146)
    at com.ibm.ws.asynchbeans.timer.TimerImpl.runListenerAsCJWork(TimerImpl.java:425)
    at com.ibm.ws.asynchbeans.am._Alarm.fireAlarm(_Alarm.java:333)
    at com.ibm.ws.asynchbeans.am._Alarm.run(_Alarm.java:230)
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1550)
Caused by: javax.transaction.RollbackException
    at com.ibm.tx.jta.TransactionImpl.stage3CommitProcessing(TransactionImpl.java:1217)
    at com.ibm.tx.jta.TransactionImpl.processCommit(TransactionImpl.java:991)
    at com.ibm.tx.jta.TransactionImpl.commit(TransactionImpl.java:913)
    at com.ibm.ws.tx.jta.TranManagerImpl.commit(TranManagerImpl.java:377)
    at com.ibm.tx.jta.TranManagerSet.commit(TranManagerSet.java:161)
    at com.ibm.ws.tx.jta.UserTransactionImpl.commit(UserTransactionImpl.java:293)
    at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1009)
    ... 37 more

In a Java program running in two Websphere nodes the following race scenario happens in a distributed transaction managed by Websphere Transaction Manager. The transaction spans across a JMS (Websphere-MQ) Transaction Source and a Database (Oracle) Transaction Source. I would like to understand

  • Why this (Exception in Thread 2, at step B6) exception happened?
    I expected no issues to happen. Thread 2 had proceeded only after making sure T1 is locked in Transaction TX2, so it is natural that Thread 1 was waiting for T1 table lock (within Transaction TX1) to be released. What I'm wondering about is that why did Thread 2 encounter a stage3CommitProcessing exception? How could I get more details about it, as the exception doesn't breathe any informtaion about it?
  • How to debug such transaction related race scenario? I know it might be difficult to reproduce. But I think there could be some Websphere related logs that I could enable to see what made the commit fail during stage3? It would be great if someone could point me in that direction.
  • How it could be avoided/resolved?

Thread 1 (Running in Websphere node 1)

A1: Start TX1
A2: Read messages (maximum of 1000 at a time) from Queue Q1
A3: LOCK TABLE T1 IN EXCLUSIVE MODE
        Got exception "ORA-02049": distributed transaction waiting for lock.  
Refer Log 1 for stack trace

Thread 2 (Running in Websphere node 2)

B1: Start TX2
B2: Read messages (maximum of 1000 at a time) from Queue Q1
B3: LOCK TABLE T1 IN EXCLUSIVE MODE
B4: Batch execute
    MERGE INTO T1 the messages read
B5: Batch insert messages into T2
B6: Commit TX2
    Got JTA transaction unexpectedly rolled back (maybe due to a timeout). Refer Log 2 for stack trace.  This was while ***stage3CommitProcessing***.

Log 1:

org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [LOCK TABLE T1 IN EXCLUSIVE MODE]; nested exception is java.sql.SQLSyntaxErrorException: ORA-02049: timeout: distributed transaction waiting for lock

at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:94)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:406)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:518)
at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.update(SimpleJdbcTemplate.java:248)
at com.test.OracleTableLock.processMessage(OracleTableLock.java:52)
at sun.reflect.GeneratedMethodAccessor833.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy153.receiveMessage(Unknown Source)
at com.test.BatchProcessor.processMessage(BatchProcessor.java:343)
at sun.reflect.GeneratedMethodAccessor779.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy155.receiveMessage(Unknown Source)
at sun.reflect.GeneratedMethodAccessor778.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
at org.springframework.scheduling.support.MethodInvokingRunnable.run(MethodInvokingRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:453)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:329)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:162)
at org.springframework.scheduling.commonj.TimerManagerTaskScheduler$TimerScheduledFuture.timerExpired(TimerManagerTaskScheduler.java:112)
at com.ibm.ws.asynchbeans.timer.TimerImpl.callListenerMethod(TimerImpl.java:298)
at com.ibm.ws.asynchbeans.timer.GenericTimer.run(GenericTimer.java:216)
at com.ibm.ws.asynchbeans.J2EEContext$RunProxy.run(J2EEContext.java:264)
at java.security.AccessController.doPrivileged(AccessController.java:224)
at javax.security.auth.Subject.doAs(Subject.java:495)
at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:131)
at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:89)
at com.ibm.ws.asynchbeans.J2EEContext$DoAsProxy.run(J2EEContext.java:335)
at java.security.AccessController.doPrivileged(AccessController.java:251)
at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1146)
at com.ibm.ws.asynchbeans.timer.TimerImpl.runListenerAsCJWork(TimerImpl.java:425)
at com.ibm.ws.asynchbeans.am._Alarm.fireAlarm(_Alarm.java:333)
at com.ibm.ws.asynchbeans.am._Alarm.run(_Alarm.java:230)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1550)
Caused by: java.sql.SQLSyntaxErrorException: ORA-02049: timeout: distributed transaction waiting for lock

at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:91)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:206)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:413)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:1034)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:183)
at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:942)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1222)
at oracle.jdbc.driver.OracleStatement.executeUpdateInternal(OracleStatement.java:1706)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:1674)
at oracle.jdbc.driver.OracleStatementWrapper.executeUpdate(OracleStatementWrapper.java:275)
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.pmiExecuteUpdate(WSJdbcStatement.java:1683)
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.executeUpdate(WSJdbcStatement.java:1041)
at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:508)
at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:1)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:395)
... 50 more

Log 2:

org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException
    at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1012)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at com.test.BatchProcessor.processMessage(BatchProcessor.java:359)
    at sun.reflect.GeneratedMethodAccessor1541.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    at java.lang.reflect.Method.invoke(Method.java:600)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy204.receiveMessage(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor1540.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    at java.lang.reflect.Method.invoke(Method.java:600)
    at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
    at org.springframework.scheduling.support.MethodInvokingRunnable.run(MethodInvokingRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:453)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:329)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java)
    at org.springframework.scheduling.commonj.TimerManagerTaskScheduler$TimerScheduledFuture.timerExpired(TimerManagerTaskScheduler.java:112)
    at com.ibm.ws.asynchbeans.timer.TimerImpl.callListenerMethod(TimerImpl.java:298)
    at com.ibm.ws.asynchbeans.timer.GenericTimer.run(GenericTimer.java:216)
    at com.ibm.ws.asynchbeans.J2EEContext$RunProxy.run(J2EEContext.java:264)
    at java.security.AccessController.doPrivileged(AccessController.java:224)
    at javax.security.auth.Subject.doAs(Subject.java:495)
    at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:131)
    at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:89)
    at com.ibm.ws.asynchbeans.J2EEContext$DoAsProxy.run(J2EEContext.java:335)
    at java.security.AccessController.doPrivileged(AccessController.java:251)
    at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1146)
    at com.ibm.ws.asynchbeans.timer.TimerImpl.runListenerAsCJWork(TimerImpl.java:425)
    at com.ibm.ws.asynchbeans.am._Alarm.fireAlarm(_Alarm.java:333)
    at com.ibm.ws.asynchbeans.am._Alarm.run(_Alarm.java:230)
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1550)
Caused by: javax.transaction.RollbackException
    at com.ibm.tx.jta.TransactionImpl.stage3CommitProcessing(TransactionImpl.java:1217)
    at com.ibm.tx.jta.TransactionImpl.processCommit(TransactionImpl.java:991)
    at com.ibm.tx.jta.TransactionImpl.commit(TransactionImpl.java:913)
    at com.ibm.ws.tx.jta.TranManagerImpl.commit(TranManagerImpl.java:377)
    at com.ibm.tx.jta.TranManagerSet.commit(TranManagerSet.java:161)
    at com.ibm.ws.tx.jta.UserTransactionImpl.commit(UserTransactionImpl.java:293)
    at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1009)
    ... 37 more

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

若相惜即相离 2024-12-06 01:25:41

假设这是一个 WebSphere MQ 资源问题,让我们尝试依次回答您的问题。

为什么会发生这个异常(线程 2 中的异常,步骤 B6)?
为什么线程 2 遇到 stage3CommitProcessing 异常?
我怎样才能获得有关它的更多详细信息?

可能是所涉及的 QMgr 尚未配置足够的日志空间来包含同步点下的所有消息。尽管您已注意序列化对数据库的访问,但队列并未序列化,因此 QMgr 必须同时在同步点下管理最多 2000 条记录。更多详细信息请参阅 QMgr 的错误日志。

如何调试此类与交易相关的竞赛场景?
是否有与 Websphere 相关的日志,我可以启用这些日志来查看导致 stage3 期间提交失败的原因?

查看 /var/mqm/qmgrs/[QMgr name]/errors/AMQERR01.log 有关是否是 WebSphere MQ 回滚事务的详细信息。

另外,打印 JMS 链接的异常。总是。 JMS 提供多级异常,其中较低级别包含特定于提供者的错误信息。通常,这些向应用程序传达的信息与您必须深入 QMgr 的错误日志才能获取的信息相同。

如果我对问题原因的判断是正确的,那么测试它的最简单方法是让两个实例尝试在同步点下分别读取 100 条记录。

如何避免/解决这个问题?

调整日志大小,以便它们可以包含在任何给定时刻可能处于同步点下的所有消息。例如,如果每条消息的大小为 1k,并且您需要在同步点下为 10 个实例中的每一个实例提供 1000 个消息,则您至少需要大约 10MB 的日志范围。这些是由 QMgr 的主要和次要日志大小和计数设置定义的。请记住,QMgr 还维护同步点,例如在管理通道时,因此无论您计算什么空间,都需要考虑通道批量大小和 QMgr 内部事务的几 MB 空间。

请参阅信息中心中有关 计算日志文件大小了解更多详细信息。有关更多背景信息,请参阅循环日志与线性日志 在 IBM DeveloperWorks 中。

Assuming that this is a WebSphere MQ resource oproblem, let's try to answer your questions in turn.

Why this (Exception in Thread 2, at step B6) exception happened?
Why did Thread 2 encounter a stage3CommitProcessing exception?
How could I get more details about it?

Chances are that the QMgr involved has not been configured with sufficient log space to contain all the messages that are under syncpoint. Although you have taken care to serialize access to the database, the queue is not serialized and so the QMgr must manage up to 2000 records under syncpoint at once. More details are available in the QMgr's error log.

How to debug such transaction related race scenario?
Are there Websphere related logs that I could enable to see what made the commit fail during stage3?

Take a look in /var/mqm/qmgrs/[QMgr name]/errors/AMQERR01.log for details of whether it was WebSphere MQ that rolled back the transaction.

Also, print the JMS linked exceptions. Always. JMS provides a multi-level exception where the lower levels contain provider-specific error information. Often these convey to the application the same information you would otherwise have to go digging through the QMgr's error logs to get.

If I'm correct about the cause of the problem, the easiest way to test it is to have two instances try to read 100 records each under syncpoint.

How it could be avoided/resolved?

Size the logs so that they can contain all of the messages that might be under syncpoint at any given moment. For example, if the messages are each 1k in size and you need 1000 of them under syncpoint for each of 10 instances, you will need at a minimum about 10MB of log extents. These are defined by the QMgr's Primary and Secondary log size and count settings. Remember that the QMgr also maintains syncpoints, for example when managing channels, and so whatever space you calculate needs to take into account channel batch sizes and a few MB for QMgr internal transactions.

Please see the section in the Infocenter on calculating log file sizes for more detail. For more background, please see Circular vs. Linear Logs in IBM developerWorks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文