EJB3 CMT中的Spring AMQP / RabbitMQ事务回滚

时间:2014-09-10 18:56:14

标签: spring rabbitmq amqp

我正在尝试测试由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>

0 个答案:

没有答案