我正在尝试测试由EJB3容器启动的事务的回滚,该事务涉及Spring JPA存储库调用以及使用Spring AMQP集成的RabbitMQ的消息发送方。在CMT回滚之后,我看到数据库事务被回滚,但消息正在传递到队列。
我正在将spring bean注入EJB中,该EJB调用Rabbit模板并且它具有@Transactional注释。我看到的是TransactionInterceptor在Spring bean发送消息调用之后提交事务。我希望它能将提交委托给容器。
任何建议/解决方法都表示赞赏。我无法在不使用@Transactional注释的情况下弄清楚如何初始化TransactionSynchronizationManager。
以下是spring bean代理执行TransactionInterceptor代码时提交事务的代码:
ResourceHolderSynchronization
@Override
public void afterCommit()
{
if (!shouldReleaseBeforeCompletion()){ -- this method returns false
processResourceAfterCommit(this.resourceHolder); -- this is calling commitAll
}
}
ConnectionFactoryUtils/RabbitResourceSynchronization
@Override
protected boolean shouldReleaseBeforeCompletion() {
return !this.transacted; -- transacted is true (channelTransacted)
}
RabbitResourceHolder
public void commitAll() throws AmqpException {
try {
for (Channel channel : this.channels) {
if (deliveryTags.containsKey(channel)) {
for (Long deliveryTag : deliveryTags.get(channel)) {
channel.basicAck(deliveryTag, false);
}
}
channel.txCommit();
}
} catch (IOException e) {
throw new AmqpException("failed to commit RabbitMQ transaction", e);
}
}
这是我的弹簧配置:
<tx:jta-transaction-manager/>
<tx:annotation-driven />
<rabbit:connection-factory id="rabbitConnectionFactory"
addresses="node01:5672,node02:5672" username="user.." password="pwd..." />
<bean id="rabbitTemplate"
class="org.arbfile.monitor.message.broker.api.rabbitmq.CustomRabbitTemplate" >
<property name="connectionFactory" ref="rabbitConnectionFactory" />
<property name="retryTemplate" ref="retryTemplate" />
<property name="exchange" value="user.example.exchange" />
<property name="queue" value="user.example.queue" />
<property name="routingKey" value="user.example.queue" />
<property name="channelTransacted" value="true" />
</bean>