从MQQueue中删除顶部消息

时间:2013-05-30 16:40:57

标签: java ibm-mq

我正在使用MQSeries构建一个消息传递系统。出于某种原因,当我执行q.get(...)时,我会抛出一个异常(我不知道具体的MQException)。以下是导致错误的代码:

private static MQGetMessageOptions GMO = new MQGetMessageOptions();
private static int GMO_OPTIONS = MQC.MQGMO_SYNCPOINT | MQC.MQGMO_WAIT;
GMO.options = GMO.options | GMO_OPTIONS;
GMO.waitInterval = MQC.MQWI_UNLIMITED;

MQEnvironment.hostname = args[0];
MQEnvironment.channel = args[2];
MQEnvironment.port = Integer.parseInt(args[1]);
MQQueueManager queueManager = new MQQueueManager(args[3])

MQMessage msg = new MQMessage();
MQQueue q = queueManager.accessQueue("qName1",MQC.MQOO_OUTPUT);
q.get(msg, GMO);

我的计划是,当发生此错误时,跳过该消息并将其删除。要执行删除,我将调用以下函数:

private void deleteMsg(MQQueueManager queueManager, String queueName) throws MQException {
    MQGetMessageOptions tempGmo = new MQGetMessageOptions();
        tempGmo.options |= MQC.MQGMO_WAIT;
        tempGmo.waitInterval = 1000;
    MQQueue remover = queueManager.accessQueue(queueName, MQC.MQOO_INPUT_AS_Q_DEF);
        remover.get(new MQMessage(), tempGmo);
        queueManager.commit();
}

在这个特定的场景中,我的deleteMsg函数中的remover.get()是否会因同样的原因失败?或者用于构造MQQueue的选项(MQC.MQOO_INPUT_AS_Q_DEF与MQC.MQOO_OUTPUT)是否也会阻止它失败?如果我在访问队列消息时遇到问题,如何丢弃最常留言并转到下一封留言?

缩短我的问题: 如果我无法在给定队列上执行get()来检索消息,我们如何在同一队列中删除该损坏的消息?

谢谢!

3 个答案:

答案 0 :(得分:4)

OMG!

MQQueue q = queueManager.accessQueue("qName1",MQC.MQOO_OUTPUT);
q.get(msg, GMO);

您正在打开输出(写入)队列,但您正在尝试收到消息。你的鞋子错了!其次,为什么不捕获MQ将抛出的MQException?例外情况会包含原因代码,它会为您提供问题的准确解释。

以下是您应该如何打开队列进行阅读:

try
{
   int oo = MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING;
   MQQueue q = queueManager.accessQueue("qName1",oo);
   MQGetMessageOptions gmo = new MQGetMessageOptions();
   gmo.options = MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING;
   q.get(msg, gmo);
}
catch (MQException e)
{
   System.err.println(e.getLocalizedMessage() );
   System.err.println("CC = " + e.completionCode + " - RC = " + e.reasonCode);
}

此外,请确保为特定的MQ API调用使用适当的“Fail if quiescing”选项。

最后,查看“退出队列”。如果您的应用程序遇到邮件问题,则应将邮件移至回退队列而不是简单地删除。

答案 1 :(得分:0)

我不知道为什么你所做的不适合你,但我想知道你为什么使用MQ系列的专有API而不是使用JMS API。在JMS术语中,删除顶部消息只是意味着接收消息,因此调用session.receieve()可以完成工作。

使用通用的JMS API有很多优点。其中最主要的是,您可以轻松地从MQ系列迁移到任何其他消息传递解决方案,而无需更改代码的一行。

答案 2 :(得分:0)

我想知道程序是否已编译,因为没有名为GMO_OPTIONS的选项。所有MQ常量都以MQC

作为前缀