[英]Spring synchronising Hibernate and JMS transactions
我正在使用一個同時使用JMS和Hibernate的應用程序。
文檔建議如果我想在兩個資源之間進行交易,則必須使用JTA。
但是,現在使用@Transaction帶注釋的DAO方法(和HibernateTransactionManager),這似乎已經起作用了。 當我在JmsTemplate上調用send()時,消息不會立即發送,而是在方法返回時使用Hibernate會話提交JMS會話。
如果沒有JtaTransactionManager,我不知道這是怎么可能的,所以我檢查了源代碼。 事實證明,Hibernate和JmsTemplate的包裝器都會使用TransactionSynchronizationManager注冊會話,並且在Hibernate會話提交時將提交JMS會話。
這和JTA交易有什么不同。 我可以用它來取代后者嗎?
簡而言之,如果沒有JTATransactionManager和XA感知數據源,您將無法獲得對兩階段提交的支持。
您目擊的是僅支持單階段提交的兩個本地事務的協調。 大致執行這一系列事件......
首先將包裝嵌套的JDBC事務啟動JMS事務,以便在Hibernate / JDBC提交失敗時回滾JMS隊列。 您的JMS偵聽器容器應設置為不 acknowledge="auto"
,而是在發送確認之前等待Hibernate事務完成。
如果您只有這兩個資源,那么您必須考慮的問題是,當Hibernate成功持久化時,您會在確認JMS服務器之前獲得異常。 這不是一個大問題,因為JMS消息不會丟失,您將再次閱讀它。
然而
您必須編寫MessageListener來處理來自服務器的重復消息
您還必須處理由於數據不良而無法處理的消息,並最終導致無限循環嘗試使用它。 在這種情況下,服務器可能配置為將消息移動到“死消息隊列”,或者您自己在MessageListener中處理此消息
其他選項和進一步閱讀
如果您的JMS服務器不支持XA(全局)事務,那么這幾乎是您唯一的解決方案。
如果JMS服務器確實支持XA事務但JDBC沒有,那么您可以使用JTATransactionManager並使用LastResourceCommitOptimisation 。 有像JOTM一樣可以使用的開源JTATransactionManagers
這篇JavaWorld文章詳細介紹了您的問題空間。
雖然Brad已經詳細解答了這個問題,但我想解決一下你查詢的一個非常具體的部分: -
如果沒有JtaTransactionManager,我不知道這是怎么回事
從spring文檔: - 當檢測到JTA環境時,Spring的JtaTransactionManager將用於管理事務
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-jta.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.