簡體   English   中英

Spring同步Hibernate和JMS事務

[英]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感知數據源,您將無法獲得對兩階段提交的支持。

您目擊的是僅支持單階段提交的兩個本地事務的協調。 大致執行這一系列事件......

  1. 啟動JMS事務
  2. 讀取JMS消息
  3. 啟動JDBC事務
  4. 寫入數據庫
  5. 提交JDBC事務
  6. 提交/確認JMS

首先將包裝嵌套的JDBC事務啟動JMS事務,以便在Hibernate / JDBC提交失敗時回滾JMS隊列。 您的JMS偵聽器容器應設置為 acknowledge="auto" ,而是在發送確認之前等待Hibernate事務完成。

如果您只有這兩個資源,那么您必須考慮的問題是,當Hibernate成功持久化時,您會在確認JMS服務器之前獲得異常。 這不是一個大問題,因為JMS消息不會丟失,您將再次閱讀它。

然而

  1. 您必須編寫MessageListener來處理來自服務器的重復消息

  2. 您還必須處理由於數據不良而無法處理的消息,並最終導致無限循環嘗試使用它。 在這種情況下,服務器可能配置為將消息移動到“死消息隊列”,或者您自己在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM