从Websphere MQ 7读取消息的独占访问权限,然后将其删除

时间:2015-11-05 15:47:01

标签: ibm-mq

我有一个队列表单,我希望能够检索邮件。然后我需要以某种方式处理它们(不在范围内),然后将它们从队列中删除。

我尝试创建了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个队列,我不知道该怎么做。

2 个答案:

答案 0 :(得分: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;
   }
}

答案 1 :(得分:2)

使用MQ时,您可以以事务方式处理消息。 因此,您应该通过使用1个输入队列并在同步点下读取该队列中的消息来满足您的要求。

因此,您的应用程序应首先在同步点下获取消息(它是一个获取消息选项),进行处理,如果成功则可以提交MQ事务,否则它可以回滚,从而将消息放回队列不变,甚至更好地将消息移动到退出队列,并使用事务性来防止应用程序中的意外错误。 此方法自动满足您的要求,即1条消息不应可用于并行读取。

无论如何,你提出的方法确实没有意义,1个消息被放到1个队列中,你如何得到你提出的两个输入队列,甚至在这样做之后,从队列中获取消息并不是&n #39; t影响消息或浏览不同队列上的游标。