4

我正在使用 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 vs MQC.MQOO_OUTPUT) 的选项是否会阻止它也失败?如果我在访问队列的消息时遇到问题,如何丢弃最上面的消息并移至下一条消息?

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

谢谢!

4

3 回答 3

4

我的天啊!

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 调用使用适当的“静默失败”选项。

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

于 2013-05-31T01:11:25.863 回答
0

我不知道为什么您正在做的事情对您不起作用,但我想知道您为什么使用 MQ 系列的专有 API 而不是使用 JMS API。在 JMS 术语中,删除顶部消息仅意味着接收消息,因此调用 ofsession.receieve()完成了工作。

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

于 2013-05-30T16:52:01.847 回答
0

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

于 2013-05-31T03:43:38.420 回答