JMS API中約定了Client端可使用四種ACK_MODE,在javax.jms.Session接口中:html
在與Spring MVC集成中 mq源碼默認 使用AUTO_ACKNOWLEDGEjava
Session.AUTO_ACKNOWLEDGE爲自動確認,客戶端發送和接收消息不須要作額外的工做。哪怕是接收端發生異常,也會被看成正常發送成功。
Session.CLIENT_ACKNOWLEDGE爲客戶端確認。客戶端接收到消息後,必須調用javax.jms.Message的acknowledge方法。jms服務器纔會看成發送成功,並刪除消息。
DUPS_OK_ACKNOWLEDGE容許副本的確認模式。一旦接收方應用程序的方法調用從處理消息處返回,會話對象就會確認消息的接收;並且容許重複確認。apache
mq消息確認設置如上。api
此外AcitveMQ補充了一個自定義的ACK_MODE: INDIVIDUAL_ACKNOWLEDGE = 4 單條消息確認服務器
咱們在開發JMS應用程序的時候,會常常使用到上述ACK_MODE,其中"INDIVIDUAL_ACKNOWLEDGE "只有ActiveMQ支持,固然開發者也可使用它. ACK_MODE描述了Consumer與broker確認消息的方式(時機),好比當消息被Consumer接收以後,Consumer將在什麼時候確認消息。對於broker而言,只有接收到ACK指令,纔會認爲消息被正確的接收或者處理成功了,經過ACK,能夠在consumer與Broker之間創建一種簡單的「擔保」機制. session
Client端指定了ACK_MODE,可是在Client與broker在交換ACK指令的時候,還須要告知ACK_TYPE,ACK_TYPE表示此確認指令的類型,不一樣的ACK_TYPE將傳遞着消息的狀態,broker能夠根據不一樣的ACK_TYPE對消息進行不一樣的操做。maven
Client端指定了ACK_MODE,可是在Client與broker在交換ACK指令的時候,還須要告知ACK_TYPE,ACK_TYPE表示此確認指令的類型,不一樣的ACK_TYPE將傳遞着消息的狀態,broker能夠根據不一樣的ACK_TYPE對消息進行不一樣的操做。spa
好比Consumer消費消息時出現異常,就須要向broker發送ACK指令,ACK_TYPE爲"REDELIVERED_ACK_TYPE",那麼broker就會從新發送此消息。在JMS API中並無定義ACT_TYPE,由於它一般是一種內部機制,並不會面向開發者。ActiveMQ中定義了以下幾種ACK_TYPE(參看MessageAck類):htm
到目前爲止,咱們已經清楚了大概的原理: Client端在不一樣的ACK_MODE時,將意味着在不一樣的時機發送ACK指令,每一個ACK Command中會包含ACK_TYPE,那麼broker端就能夠根據ACK_TYPE來決定此消息的後續操做. 接下來,咱們詳細的分析ACK_MODE與ACK_TYPE.對象
ActiveMQ有支持兩種事務,
在支持事務的session中,producer發送message時在message中帶有transaction ID。broker收到message後判斷是否有transaction ID,若是有就把message保存在transaction store中,等待commit或者rollback消息。因此ActiveMq的事務是針對broker而不是producer的,無論session是否commit,broker都會收到message。
若是producer發送模式選擇了persistent,那麼message過時後會進入死亡隊列。在message進入死亡隊列以前,ActiveMQ會刪除message中的transaction ID,這樣過時的message就不在事務中了,不會保存在transaction store中,會直接進入死亡隊列。具體刪除transaction ID的地方是在
org.apache.activemq.util.BrokerSupport的doResend,將transaction ID保存在了originalTransactionID中,刪除了transaction ID