Почему откат транзакции во время stage3CommitProcessing?

3

В Java-программе, запущенной в двух узлах Websphere, в распределенной транзакции, управляемой Websphere Transaction Manager, происходит следующий гоночный сценарий. Транзакция проходит через источник транзакций JMS (Websphere-MQ) и источник транзакций базы данных (Oracle). Я хотел бы понять

  • Почему произошло это (исключение в потоке 2, на этапе B6)? Я не ожидал никаких проблем. Поток 2 продолжался только после того, как T1 заблокирован в Transaction TX2, поэтому естественно, что Thread 1 ожидал, что блокировка таблицы T1 (в транзакции TX1) будет выпущена. Мне интересно, почему Thread 2 столкнулся с исключением stage3CommitProcessing? Как я могу получить более подробную информацию об этом, поскольку исключение не вдыхает никакой информации об этом?
  • Как отладить такой сценарий, связанный с транзакциями? Я знаю, что это может быть трудно воспроизвести. Но я думаю, что могут быть некоторые журналы, связанные с Websphere, которые я могу позволить увидеть, что сделало ошибку коммита во время stage3? Было бы здорово, если бы кто-то мог указать мне в этом направлении.
  • Как его можно было бы избежать/разрешить?

Тема 1 (Работа в 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

Тема 2 (Работа в 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***.

Журнал 1:

org.springframework.jdbc.BadSqlGrammarException: StatementCallback; плохая грамматика SQL [LOCK TABLE T1 IN EXCLUSIVE MODE]; inested exception is java.sql.SQLSyntaxErrorException: ORA-02049: таймаут: распределенная транзакция, ожидающая блокировки

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
Теги:
ibm-mq
websphere
distributed-transactions

1 ответ

1

Предполагая, что это ресурс WebSphere MQ, попробуйте ответить на ваши вопросы по очереди.

Почему произошло исключение (исключение в потоке 2, на этапе B6)?
Почему в Thread 2 возникло исключение stage3CommitProcessing?
Как я могу получить более подробную информацию об этом?

Скорее всего, QMgr не был сконфигурирован с достаточным пространством журнала, чтобы содержать все сообщения, находящиеся под синхронизацией. Хотя вы позаботились о сериализации доступа к базе данных, очередь не сериализована, поэтому QMgr должен одновременно управлять до 2000 записей под синхронизацией. Более подробная информация доступна в журнале ошибок QMgr.

Как отладить такой сценарий, связанный с транзакциями?
Существуют ли журналы, связанные с Websphere, которые я могу разрешить, чтобы увидеть, что сделало коммит неудачным во время stage3?

Взгляните в /var/mqm/qmgrs/[QMgr name]/errors/AMQERR01.log для получения информации о том, что именно WebSphere MQ откатил транзакцию.

Кроме того, напечатайте связанные JMS исключения. Всегда. JMS предоставляет многоуровневое исключение, где нижние уровни содержат информацию об ошибках поставщика. Часто они передают приложению ту же самую информацию, которую вам в противном случае пришлось бы искать в журналах ошибок QMgr, чтобы получить.

Если я правильно разбираюсь в причине проблемы, самый простой способ проверить это - заставить два экземпляра попытаться прочитать по 100 записей каждый в точке синхронизации.

Как его можно было бы избежать/разрешить?

Размер журналов, чтобы они могли содержать все сообщения, которые могут находиться под синхронизацией в любой момент. Например, если сообщения имеют размер 1k и вам нужно 1000 из них по синхронной точке для каждого из 10 экземпляров, вам потребуется минимум 10 МБ экстентов журнала. Они определяются параметрами QMgr Primary и Secondary log size и count. Помните, что QMgr также поддерживает синхронизирующие точки, например, при управлении каналами, и поэтому любое пространство, которое вы вычисляете, должно учитывать размеры пакетов каналов и несколько МВ для внутренних транзакций QMgr.

Подробнее см. раздел в Инфоцентре расчёт размеров файлов журнала. Дополнительную информацию см. В Circular vs. Linear Logs в IBM developerWorks.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню