【问题标题】:Delete top message from MQQueue从 MQQueue 中删除顶部消息
【发布时间】:2013-05-31 22:49:40
【问题描述】:

我正在使用 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() 来检索消息,我们如何删除同一队列上的损坏消息?

谢谢!

【问题讨论】:

    标签: java ibm-mq


    【解决方案1】:

    天哪!

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

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

    【讨论】:

    • 感谢您的意见。我正在捕获 MQException,但不幸的是,我创建的日志不再存在。所以我无法确定确切的例外情况。我会看看你的其他建议,谢谢。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 抱歉,我遗漏了 GMO_OPTIONS 的设置。我编辑了上面的代码。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 2013-11-10
      • 1970-01-01
      • 1970-01-01
      • 2011-12-29
      相关资源
      最近更新 更多