我需要使用IBM Websphere Liberty Core Tx Manager和ActiveMQ作为Broker进行XA事务。 制作人工作得很好,但消费者并没有“回滚”#34;失败后的消息。
消费者被定义为:
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="cachedConnectionFactory"/>
<property name="destination" ref="queue"/>
<property name="messageListener" ref="messageListener"/>
<property name="transactionManager" ref="transactionManager" />
</bean>
Tx定义为:
<tx:jta-transaction-manager />
Connection Factory是ActiveMQXAConnectionFactory的实例。
我的messageListener抛出RuntimeException,这导致在Spring Code中将标志设置为ReadOnly。有趣的部分是在这个Snipped of Spring代码中:
protected boolean receiveAndExecute(Object invoker, Session session, MessageConsumer consumer)
throws JMSException {
if (this.transactionManager != null) {
// Execute receive within transaction.
TransactionStatus status = this.transactionManager.getTransaction(this.transactionDefinition);
boolean messageReceived;
try {
messageReceived = doReceiveAndExecute(invoker, session, consumer, status);
}
catch (JMSException ex) {
rollbackOnException(status, ex);
throw ex;
}
catch (RuntimeException ex) {
rollbackOnException(status, ex);
throw ex;
}
catch (Error err) {
rollbackOnException(status, err);
throw err;
}
this.transactionManager.commit(status);
return messageReceived;
}
else {
// Execute receive outside of transaction.
return doReceiveAndExecute(invoker, session, consumer, null);
}
}
方法doReceiveAndExecute正确调用侦听器,并将Tx标记为rollbackOnly。但是,它会消耗RuntimeException,因为它可以在下面的代码中显示,因此根本不会调用rollbackOnException。
这是在AbstractPollingMessageListenerContainer类中剪切的异常消费者
catch (Throwable ex) {
if (status != null) {
if (logger.isDebugEnabled()) {
logger.debug("Rolling back transaction because of listener exception thrown: " + ex);
}
status.setRollbackOnly();
}
handleListenerException(ex);
// Rethrow JMSException to indicate an infrastructure problem
// that may have to trigger recovery...
if (ex instanceof JMSException) {
throw (JMSException) ex;
}
}
我是否遗漏了某些内容,或者是Spring代码或其他地方的错误?我的Spring-jms版本是4.0.5.RELEASE
---更新---
使用Active MQ的XA事务存在很大问题。
我们从Liberty连接到Active MQ(远程)。如果我们在XA模式下使用WLC TX Manager, Active MQ中没有回滚(如果是异常)。
如果我们为 Atomikos Tx经理更改Tx经理,一切正常。 (如果出现问题,我们会回滚,并且消息会保留在队列中......)
因此,与XA连接工厂合作的WLC Tx Manager或WLC Tx Manager可能存在问题... :(嗯,这意味着WLC tx管理器在Spring + WLC + ActiveMQ + XA中有问题堆栈。
我们向IBM提出了一个问题并等待响应。
更新:
@Bean
public ConnectionFactory connectionFactory() throws NamingException {
ActiveMQXAConnectionFactory cf = (ActiveMQXAConnectionFactory) activeMqInitialContext().lookup("XAConnectionFactory");
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setInitialRedeliveryDelay(500);
redeliveryPolicy.setUseExponentialBackOff(true);
redeliveryPolicy.setMaximumRedeliveries(-1);
cf.setRedeliveryPolicy(redeliveryPolicy);
return cf;
}
<bean id="cachedConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="connectionFactory" />
</bean>
<bean id="eStampMessageListener" class="sk.posta.ekolky.oek.jms.EStampMessageListener" />