2011-08-10 17 views
3

2つのWebsphereノードで実行されているJavaプログラムでは、Websphere Transaction Managerによって管理される分散トランザクションで次の競合シナリオが発生します。トランザクションは、JMS(Websphere-MQ)トランザクションソースとデータベース(Oracle)トランザクションソースにまたがっています。私は理解したいと思いますステージ3コミット処理中にトランザクションがロールバックされたのはなぜですか?

  • なぜこの(スレッド2の例外、ステップB6で)例外が発生しましたか? 私は何の問題も起こらないと思った。スレッド2は、トランザクションTX2でT1がロックされていることを確認した後にのみ進行していたので、スレッド1が(トランザクションTX1内で)T1テーブルロックが解放されるのを待っていたのは自然なことです。私は、なぜスレッド2がstage3CommitProcessing例外に遭遇したのでしょうか?例外がそれについての情報を呼吸しないので、どのように私はそれについての詳細を得ることができますか?
  • このようなトランザクション関連の競合シナリオをデバッグするにはどうすればよいですか?私はそれが再現するのが難しいかもしれないことを知っています。しかし、私は、Websphere関連のログがいくつかあり、ステージ3でコミットが失敗した原因を調べることができると思いますか?もし誰かが私をその方向に向けることができれば素晴らしいだろう。
  • どのように回避/解決できましたか? (WebSphereノードで実行1)

スレッド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];ネストされた例外はjava.sql.SQLSyntaxErrorExceptionです:ORA-02049:タイムアウト:ログイン2ロック

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 

を待っている分散トランザクション:

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 

答えて

1

これは、WebSphereであると仮定すると、 MQリソースの問題では、あなたの質問に順番に答えてみましょう。

なぜ(スレッド2の例外、ステップB6の例外)例外が発生したのですか?
なぜスレッド2でstage3CommitProcessing例外が発生しましたか?
どうすれば詳細を知ることができますか?

関連するQMgrに、同期点の下にあるすべてのメッセージを格納するのに十分なログスペースが設定されていない可能性があります。データベースへのアクセスをシリアライズしても、キューはシリアライズされないため、QMgrは同期ポイントの下で同時に最大2000個のレコードを管理する必要があります。詳細は、QMgrのエラーログを参照してください。

このようなトランザクション関連の競合シナリオをデバッグするにはどうすればよいですか?
ステージ3でコミットが失敗した原因を確認するために有効にできるWebsphere関連のログはありますか?

トランザクションをロールバックしたWebSphere MQであるかどうかについては、/var/mqm/qmgrs/[QMgr name]/errors/AMQERR01.logを参照してください。

また、JMSリンク例外も表示します。常に。 JMSは、下位レベルにプロバイダ固有のエラー情報が含まれる複数レベルの例外を提供します。 QMgrのエラーログを掘り下げて取得する必要のある情報と同じ情報をアプリケーションに伝えることがよくあります。

問題の原因が正しい場合、それをテストする最も簡単な方法は、2つのインスタンスがそれぞれ同期点の下で100個のレコードを読み取ろうとすることです。

どのように回避/解決できましたか?

任意の時点で同期点の下にある可能性があるすべてのメッセージを含めることができるようにログのサイズを設定します。たとえば、メッセージのサイズが1kで、10インスタンスごとに同期点の下に1000個のメッセージが必要な場合は、最低でも約10MBのログエクステントが必要になります。これらは、QMgrの1次および2次ログ・サイズおよびカウント設定によって定義されます。 QMgrは、たとえばチャネルを管理するときなど、シンクポイントも保持するため、チャネルのバッチサイズを考慮する必要があります。また、QMgr内部トランザクションの場合は数MB必要です。

詳細については、インフォセンターのcalculating log file sizesのセクションを参照してください。詳細は、developerWorksのCircular vs. Linear Logsを参照してください。

関連する問題