2012-12-15 42 views
5

數據庫事務是一個熟悉的概念。JMS事務

try { 
    ... 
    .. 
    updateDB() 
    .. 
    ... 
    commit(); 
} catch error { 
    rollback(); 
} 

如果發生任何錯誤,updateDB所做的任何更改都將被丟棄。

我想知道什麼消息隊列事務回滾將撤消。

try{ 
    ... 
    ... 
    //EDIT: swapped the order of receive and send 
    Message m = queue1.receiveMessage(..) 
    .. 
    .. 
    queue2.sendMessage(..) 
    .. 
    .. 
    commit(); 
} catch error { 
    rollback(); 
} 

具體而言,究竟會回滾做

  1. 取消消息的發送
  2. 未收到,即放回接收 消息回到隊列

消息還是我我把數據庫tx比喻得太過分了。

感謝

編輯:我不是暗示的發送和接收操作是相關的。我只是想說有兩個操作會改變消息代理的狀態 - 接收消息會從隊列中取出消息,如果有其他消費者,消息將不可用。

回答

9

發送的回滾是直接的,消息不會被放入隊列2。

接收回滾通常會將消息放回隊列(隊列1)。 根據您的JMS提供程序設置和配置,該消息將多次重新發送。如果事務回滾次數太多(可配置太多),它將被置於「退出隊列」(或死信隊列),以便它不會阻塞其他消息的隊列。退出的消息通常需要一些手動錯誤處理。

0

是的,你正在把它拉得太遠。

在事務處理模式下,您的queue.receiveMessage()將永遠不會返回(假設它設置爲等待特定回覆消息,而不僅僅是「任何」消息),因爲queue.sendMessage()並未真正發送消息(它會在交易提交時發送)。

順便說一下,這是一個常見的錯誤。當使用JMS(異步協議)進行同步通信時,將發送/接收週期視爲由一個事務組成是很自然的。但是,情況並非如此。一旦你在交易模式下發行sendMessage(),目前還沒有真正發生;該消息將僅在事務提交時發送。

+0

感謝您的見解。但我並不是暗示我在等待發送消息的回覆,只是想指出狀態的兩個變化。我已經添加了對我的問題的解釋並交換了接收/發送消息的順序。 – mzzzzb