我的WebSphere应用程序基于Spring构建,并使用分布式事务(aka XA,2PC,全局事务)访问JMS(MQ)和JDBC(DB2)XA资源。
我想在需要进行事务处理的地方使用Spring的TransactionTemplate
。在许多地方都可以正常工作。
但是,在某个地方,TransactionTemplate
的使用会导致事务问题,而使用PlatformTransactionManager
的等效实现则有效。
带有PlatformTransactionManager
的代码(可以正常工作):
protected static final TransactionDefinition NEW_TX = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
...
protected void runSingleBatch(...) {
final TransactionStatus status = getTransactionManager().getTransaction(NEW_TX);
try {
// do my business with JMS (MQ) and JDBC (DB2)
getTransactionManager().commit(status);
} catch (Throwable e) {
if (!status.isCompleted()) {
getTransactionManager().rollback(status);
}
throw e;
}
}
带有TransactionTemplate
的代码(失败):
protected static final TransactionDefinition NEW_TX = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
...
protected void runSingleBatch(...) {
final TransactionTemplate transactionTemplate = new TransactionTemplate(getTransactionManager(), NEW_TX);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// do my business with JMS (MQ) and JDBC (DB2)
}
});
}
TransactionTemplate变体在WebSphere中由于以下原因而失败:
[9/19/18 19:32:55:299 CEST] 000001bb LocalTranCoor E WLTC0007E: Cannot enlist Resource for cleanup because a global transaction is active.
[9/19/18 19:32:55:299 CEST] 000001bb LocalTransact E J2CA0030E: Method enlist caught java.lang.IllegalStateException: Cannot enlist Resource for cleanup. A Global transaction is active.
at com.ibm.tx.ltc.impl.LocalTranCoordImpl.enlistForCleanup(LocalTranCoordImpl.java:395)
at com.ibm.ejs.j2c.LocalTransactionWrapper.enlist(LocalTransactionWrapper.java:767)
at com.ibm.ejs.j2c.ConnectionEventListener.localTransactionStarted(ConnectionEventListener.java:860)
at com.ibm.ejs.jms.JMSManagedSession.localTransactionStarted(JMSManagedSession.java:860)
at com.ibm.ejs.jms.JMSManagedSession.enlist(JMSManagedSession.java:821)
at com.ibm.ejs.jms.JMSMessageConsumerHandle.enlist(JMSMessageConsumerHandle.java:810)
at com.ibm.ejs.jms.JMSMessageConsumerHandle.receiveNoWait(JMSMessageConsumerHandle.java:615)
at com.tsystems.cc4.inbound.scanner.jms.QueueAccessor.receiveNextMessage(QueueAccessor.java:83)
at com.tsystems.cc4.inbound.scanner.jms.JmsBatchTriggerScanner.run(JmsBatchTriggerScanner.java:90)
at com.tsystems.cc4.inbound.execution.batch.BatchExecutor$1.doInTransactionWithoutResult(BatchExecutor.java:183)
at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:34)
at org.springframework.transaction.jta.WebSphereUowTransactionManager$UOWActionAdapter.run(WebSphereUowTransactionManager.java:365)
at com.ibm.ws.uow.embeddable.EmbeddableUOWManagerImpl.runUnderNewUOW(EmbeddableUOWManagerImpl.java:791)
at com.ibm.ws.uow.embeddable.EmbeddableUOWManagerImpl.runUnderUOW(EmbeddableUOWManagerImpl.java:370)
at org.springframework.transaction.jta.WebSphereUowTransactionManager.execute(WebSphereUowTransactionManager.java:293)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:127)
at com.tsystems.cc4.inbound.execution.batch.BatchExecutor.runSingleBatch(BatchExecutor.java:175)
...
while trying to enlist resources from DataSource JMS$... (...)$JMSManagedConnection@33 with the Transaction Manager for the current transaction, and threw a Exception.
为什么PlatformTransactionManager
变体不能起作用,而TransactionTemplate
变体却不能起作用?