2013-01-10 78 views
0

我使用JTA,兩階段提交,JMS和JDBC事務處理結構。這個想法是(簡稱)以如何在提交時使用JTA確認JMS消息?

  1. 收到一條消息在隊列上
  2. 執行一些數據庫操作
  3. 確認該消息,當數據庫操作已經成功

所以我就XAQueueConnectionFactory,創建XAQueueSession,從會話創建接收器並設置消息監聽器。

在偵聽器內部,在onMessage方法中,我開始我的用戶事務,執行jdbc的東西並提交事務或執行回滾,如果出現錯誤。現在,我期望(又稱「希望」)在用戶事務提交時確認該消息。

但是,這並沒有發生,消息仍然在隊列中,並一次又一次地重新遞送。

我錯過了什麼?我仔細檢查了會話,確認模式確實是「SESSION_TRANSACTED」,getTransacted返回true。

我沒有Java EE容器,沒有彈簧,沒有消息驅動的bean。我使用獨立的JTA bitronix。

回答

0

當你在監聽器中說你開始你的用戶事務時,這似乎暗示你正在使用Bean Managed Transaction(BMT)。這樣做有充分的理由嗎?

如果您使用容器管理的交易(CMT),你想要什麼免費。

據我所知,這是不可能與BMT,因爲UserTransaction不會參與,並將不能參與爲消息創建的事務。但是您可能需要仔細檢查Java EE規範。

編輯: 對不起,我意識到太遲了,你沒有使用Java EE容器。

您確定在偵聽器中啓動的用戶事務是爲消息啓動的事務的一部分嗎?看來,你開始一個獨立的數據庫工作事務。

如果您不使用容器,誰提供JMS實現,即XAQueueConnectionFactory等?

2

你並不真的需要XA。只需遵循你的算法:接收消息,執行數據庫操作,然後確認消息...從字面上看,這就是解決方案。 (而是一個事務會話,你可能會選擇明確的CLIENT_ACKNOWLEDGE。)如果你的應用程序在執行數據庫操作時失敗了,不要回復JMS消息,它會被重新發送。如果您的應用程序在數據庫txn之後和確認之前失敗,則該消息將被重新傳遞 - 但您可以檢測到此消息(消息中的重新傳遞的標誌將設置爲true),並且您可以決定是否重新處理該消息,基於數據庫的狀態。

0

我覺得在XA你不會使用事務處理會話。