我正在使用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