2010-12-09 28 views
3

我們將.NET API用於IBM的WebSphere MQ。重用IBM.WMQ.MQQueue對象

創建MQQueueManager對象顯然是一個昂貴的操作,因此我們緩存並重用這些對象池。

目前,對於每一個請求,我們訪問所需的隊列:

//obtain queueManager from pool 
IBM.WMQ.MQQueue requestQ= queueManager.AccessQueue(requestQName, mqOptions); 
IBM.WMQ.MQQueue responseQ= queueManager.AccessQueue(responseQName, mqOptions); 

,並關閉它們做一次:

requestQ.Close(); 
responseQ.Close(); 

這是最好的做法,或者我們應該也集中和重用MQQueue對象(除了隊列管理器)? AccessQueue()在客戶端上似乎是一個便宜的操作。

回答

1

答案取決於您的線程模型和事務性。通常,消息傳遞客戶端應始終使用事務性,即使這只是單階段提交。原因是結果的含糊不清,否則會導致重複或丟失的消息。我已經提供了關於in another answer的更詳細的解釋。

問題是事務是連接範圍的。當你提交時你這樣做了整個連接。在多個線程之間安全地使用相同的連接將阻止使用事務,從而使應用程序丟失或重複的消息。由於隊列句柄僅在特定連接的上下文中有效,因此它們將繼承線程模型和連接池。

服務提供者應用程序最常見的模型是在輸入隊列上維護每個線程的連接並動態地打開/放入/關閉輸出隊列。例如,在一個工作單位......

  1. 閱讀下一個請求消息
  2. 使用回覆信息獲取目的地
  3. 打開應答隊列
  4. 把響應
  5. 提交
  6. 銷燬回覆到目標對象,從而關閉該應答隊列

在這種情況下,連接不會不斷重建,也不會關閉輸入隊列。但是,它確實需要每個線程保持專用連接。

+0

那麼你說「連接」,你是什麼意思?我看到IBM文檔也提到了它,但是因爲我認爲我連接到QueueManager,所以我不太瞭解是否需要爲每個線程創建新的QM(緩存)。 – 2016-10-28 16:15:30