2015-11-05 75 views
0

我有一個隊列表,我希望能夠檢索消息。然後我需要以某種方式處理它們(不在範圍內),然後將它們從隊列中移除。獨家訪問從Websphere MQ 7讀取消息,然後將其刪除

我試着創建2個隊列,一個瀏覽消息,一個消息處理後刪除消息。

MQQueue browseQueue = qMgr.AccessQueue(QUEUE_NAME, MQC.MQOO_BROWSE); 
    MQGetMessageOptions browseOptions = new MQGetMessageOptions() 
    { 
     Options = MQC.MQGMO_WAIT | MQC.MQPMO_FAIL_IF_QUIESCING | MQC.MQGMO_BROWSE_NEXT, 
     WaitInterval = MQC.MQWI_UNLIMITED 
    }; 

    MQQueue acknowledgeQueue = qMgr.AccessQueue(QUEUE_NAME, MQC.MQOO_INPUT_AS_Q_DEF); 
    MQGetMessageOptions acknowledgeOptions = new MQGetMessageOptions() 
    { 
     Options = MQC.MQGMO_WAIT | MQC.MQPMO_FAIL_IF_QUIESCING | MQC.MQMO_MATCH_MSG_ID, 
     WaitInterval = MQC.MQWI_UNLIMITED 
    }; 

    while (keepRunning.WaitOne(0)) 
    { 
     MQMessage browseMessage = new MQMessage(); 

     try 
     { 
      browseQueue.Get(browseMessage, browseOptions); 
     } 
     catch (MQException mqexe) 
     { 
      throw; 
     } 

     if (browseMessage.MessageType != ShutDown.TYPE) 
     { 
      object o = browseMessage.ReadObject(); 
      Console.WriteLine("The message is: {0}", o); 
     } 

     browseMessage.ClearMessage(); 

     MQMessage acknowledgeMessage = new MQMessage() 
     { 
      MessageId = browseMessage.MessageId 
     }; 
     acknowledgeQueue.Get(acknowledgeMessage, acknowledgeOptions); 
    } 

但我需要確保沒有其他進程可以訪問相同的消息。因爲,我依靠使用2個隊列,我不知道該怎麼做。

回答

3

育克。你不瞭解MQ。正如Attila所說,您需要使用MQ SyncPoint,並且如果您對該消息感到滿意,請將其提交,否則將其退出。另外,不要在程序中對隊列管理器或隊列名進行硬編碼,你應該從屬性文件中讀取它們。

下面是代碼應該是什麼樣子:

MQQueueManager qMgr = new MQQueueManager(qMgrName); 
MQQueue queue = qMgr.AccessQueue(qName, MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING); 
MQGetMessageOptions gmo = new MQGetMessageOptions(); 
gmo.Options = MQC.MQGMO_WAIT | MQC.MQGMO_FAIL_IF_QUIESCING | MQC.MQGMO_SYNCPOINT; 
gmo.WaitInterval = MQC.MQWI_UNLIMITED; 
MQMessage receiveMsg; 

while (keepRunning.WaitOne(0)) 
{ 
    receiveMsg = new MQMessage(); 

    try 
    { 
     queue.Get(receiveMsg, gmo); 
     if (receiveMsg.MessageType != ShutDown.TYPE) 
     { 
      object o = receiveMsg.ReadObject(); 
      Console.WriteLine("The message is: {0}", o); 
     } 

     qMgr.Commit(); 
    } 
    catch (MQException mqexe) 
    { 
     qMgr.Backout(); 
     throw mqexe; 
    } 
} 
+0

這會防止另一個線程訪問相同的消息,該消息已被檢索'queue.Get(receiveMsg,GMO)之後;'但經理之前COMMITED? –

+0

是的,在得到消息後,它不可用於其他線程,直到它被退出(假設它已退出)。 –

2

您可以在使用MQ時事務性地處理消息。 因此,通過使用1個輸入隊列並在同步點下讀取來自該隊列的消息,可以滿足您的要求。因此,你的應用程序應該首先在同步點(它是一個get消息選項)下獲得消息,進行處理,如果成功,它可以提交MQ事務,否則它可以回滾它,從而將消息放回到隊列不變,或者甚至更好地將消息移動到退出隊列並使用事務性來防止應用程序中出現意外錯誤。 此方法自動滿足您的要求,即1條消息不應用於並行讀取。

無論如何,你提出的方法並沒有什麼意義,1條消息放到1個隊列中,你如何將它提交給你提出的兩個輸入隊列,甚至在這樣做之後,從隊列中獲取消息不會'不會影響消息或瀏覽不同隊列上的遊標。