2012-11-17 62 views
3

我已經觀察到,當MSG從隊列中讀取(破壞性呼叫)後,如果TX被回滾(MDB容器管理TX)MSG被放置回隊列(原始或回取決於隊列的門檻設置&)。可以說,如果由於TX的回滾失敗而導致某些事情發生(重複網絡問題或某些問題),則Msgs將丟失。讀消息始終破壞性呼叫

是真的嗎?

謝謝

回答

1

不會丟失消息。在事務中,只有成功提交後纔會從隊列中刪除消息。如果提交或回滾失敗,則消息將重新出現。如果在調用提交或回滾之前應用程序和隊列管理器之間的連接中斷,WebSphere MQ將自動執行回滾。這確保消息不會丟失。

3

正如我在評論早前指出的問題,簡單的答案是「沒有,如果COMMIT失敗WMQ不會丟失這些消息」,但讓我們來看看在一些詳細信息。

當客戶機在網絡上MQ的連接,是什麼在幕後發生的是,MQ啓動創建共享內存連接到MQ和插座連接到客戶端應用程序的過程。保持交易開放的東西是共享存儲過程,在WMQ術語中稱爲「渠道代理」。

有兩種情況COMMIT從應用程序的角度來看似乎已經失敗。在其中的第一個中,COMMIT被傳遞到通道代理並被執行,但是由於網絡問題,確認永遠不會將其返回到應用程序。從MQ的角度來看,由於該應用程序故意承諾致電GET,因此該消息不會「丟失」。

第二種情況是,COMMIT到達通道代理之前發生了網絡故障。在這種情況下,COMMIT確實失敗了,因爲應用程序無法恢復事務所在的連接句柄。當通道代理認識到TCP連接失敗時,它將退出事務並關閉通道。這個過程中的皺紋是渠道代理可能需要一段時間才能意識到連接已經死亡。實際上,大多數平臺上的默認TCP超時時間爲兩個小時。根據您的服務器的TCP設置,事務處理GET可能會在同步點下持有該消息長達兩個小時,使其看起來已被佔用。這是強烈建議使用當前級別的QMgr和客戶端的原因之一 - 它們更少依賴於TCP,並且更多依靠內部信道心跳協議來檢測丟失的連接。

從應用程序的角度來看,這兩種情況看起來都是一樣的 - 應用程序調用COMMIT並取回2009 MQRC_CONNECTION_BROKEN。但在第一種情況下,消息由於COMMIT而消失,並且在第二種情況下,消息可能再次被傳遞。由於這種模糊性,應用程序必須能夠檢測並正常處理重複消息。

現在宣稱這是MQ缺陷之前,讓我指出,這種不確定性結果的使用時的消息在網絡上,而不是具體到WebSphere MQ東西是與生俱來的。事實上,JMS 1.1 specification直接在4.4中解決了這個問題。13,它說:

如果時間之間發生故障的客戶端提交上 會議的工作,並提交方法返回時,客戶端不能確定是否 事務提交或回滾。當在發送方法的返回時發生在 PERSISTENT消息的非事務性發送之間發生故障時,存在相同的模糊性 。

這是由JMS應用程序來處理這種模糊性。在某些 的情況下,這可能會導致客戶端生成功能重複的 消息。

由於會話恢復而重新發送的消息不是 被視爲重複消息。

所以使用同步點可以消除丟失消息的情況下,因爲任何GET必須以永久地從隊列中移除該消息中接着是COMMIT。根據定義,COMMIT不能到達,直到應用程序看到該消息。但是,同步點無法消除重複郵件的可能性,因爲如果GETCOMMIT失敗,則應用程序可能會再次看到該郵件。同樣,如果PUTCOMMIT失敗,則應用程序無法知道COMMIT在到達通道代理之前或之後是否失敗,並且別無選擇,只能重新連接,並且再次請求PUT消息。

事實上,如果你正在經歷「丟失」的消息,可能性是:

  1. 的把應用程序未能在COMMIT,但並沒有把消息的另一個副本。
  2. GET丁應用程序在COMMIT上失敗,並且消息不會丟失,但實際上在同步點之下。在這種情況下,請停止任何孤立通道以回滾事務。

除了這兩種情況之外,WMQ不會丟失該持久性消息。