Мое приложение WebSphere построено на основе Spring и использует распределенные транзакции (также известные как XA, 2PC, глобальные транзакции) для доступа к ресурсам JMS (MQ) и JDBC (DB2) XA.
Я хочу использовать * 1003 Spring* где мне нужно сделать собственную обработку транзакций.Это прекрасно работает во многих местах.
Однако в одном месте использование 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
нет?