事务与PlatformTransactionManager一起使用,但与TransactionTemplate一起失败

时间:2018-09-20 09:55:00

标签: spring transactions jms websphere mq

我的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变体却不能起作用?

0 个答案:

没有答案