我正在使用spring amqp将消息放置在EJB(无状态会话Bean)中的Rabbit队列中。由EJB事务管理器管理的Rabbit AMQPTemplate消息
当EJB容器抛出异常时回滚数据更新,是否有办法让EJB容器以类似的方式管理消息的发送,以便它只在EJB完成而没有抛出异常?
我正在使用spring amqp将消息放置在EJB(无状态会话Bean)中的Rabbit队列中。由EJB事务管理器管理的Rabbit AMQPTemplate消息
当EJB容器抛出异常时回滚数据更新,是否有办法让EJB容器以类似的方式管理消息的发送,以便它只在EJB完成而没有抛出异常?
做到这一点的最好办法是:
获取所有
使用Spring TX经理
而且RabbitTemplate
摆脱EJB将做TX同步的东西给你自动。
与EJB TX同步(提交或回滚),其RabbitTemplate
没有看到当前的TX,因为它不是由Spring管理的问题。
如果可以将该EJB作为Spring bean,那么您将能够为EJB容器事务提供JtaTransactionManager
,并用@Transactional
标记EJB方法。但是在这种情况下,EJB并没有发挥作用,因为我们在这里对Spring做了许多工作。
RabbitMQ没有支持XA的驱动程序,因此不能由容器管理,您可以做的最好的方法是在模板上设置channelTransacted
,并使用doInRabbit()
方法将EJB代码范围设置为...
template.execute(new ChannelCallback<Object>() {
@Override
public Object doInRabbit(Channel channel) throws Exception {
/// MDB logic + channel.basicPublish()
}
});
然后,如果抛出异常,两个事务都会回滚。
但是,如果EJB提交失败,rabbit发布将已经提交并且不会回滚,所以您应该计划处理(罕见)重复。
谢谢,我无法找到很多的ChannelCallback的文档的方式我看到,我将不得不使用RabbitTemplate而不是AmqpTemplate是否正确? – 2014-11-24 17:46:44
执行命令是否立即运行,它是异步的吗?欢呼 – 2014-11-24 17:47:34
http://docs.spring.io/spring-amqp/docs/latest-ga/api/org/springframework/amqp/rabbit/core/ChannelCallback.html它在调用线程上运行。 – 2014-11-24 17:56:20
谢谢,不幸的是,目前计划从技术堆栈中删除EJB,所以这种方式不适合我。可能是为了其他人,尽管那些不太愿意重构EJB。 – 2014-11-24 17:31:12