【发布时间】:2016-12-20 14:32:54
【问题描述】:
我有一个应用程序正在侦听 IBM Websphere MQ 队列上的消息。 一旦消息被消费,应用程序就会执行一些处理逻辑。 如果处理完成正常,我希望应用程序确认消息并将其从队列中删除。 如果在处理过程中发生错误,我希望消息保留在队列中。 这是如何实施的? (我正在使用 .NET API) 谢谢。
【问题讨论】:
-
您好,您的答案在代码中吗?
标签: ibm-mq
我有一个应用程序正在侦听 IBM Websphere MQ 队列上的消息。 一旦消息被消费,应用程序就会执行一些处理逻辑。 如果处理完成正常,我希望应用程序确认消息并将其从队列中删除。 如果在处理过程中发生错误,我希望消息保留在队列中。 这是如何实施的? (我正在使用 .NET API) 谢谢。
【问题讨论】:
标签: ibm-mq
MQ 支持单阶段提交协议。您在收到消息时指定同步点,然后根据需要发出COMMIT 或ROLLBACK。如果连接丢失,默认操作是ROLLBACK,如果程序故意结束而不解决事务,则假定为COMMIT。 (这取决于平台,因此习惯上的建议是显式调用COMMIT,而不是依赖类析构函数为您执行此操作。)
无论消息是否持久,这都有效。但是,如果消息指定了过期时间并且在回滚后过期,则有可能不会再次看到它。
当然,如果程序发出ROLLBACK,则通常会再次看到该消息,因为它会返回到队列中的同一位置,并且对于位于顶部的 FIFO 队列。如果消息的问题不是暂时的,那么这会导致读取/回滚/重复的有害消息循环。为避免应用程序可以检查回退计数,如果它超过某个阈值,则将消息重新排队到异常队列。
当使用 JMS 或 XMS 时,这些是由类库为您完成的。如果输入队列的BOQNAME 和BOQTHRESH 属性被设置,则requeue 是BOQNAME 中的队列名称。否则尝试重新排队到死队列。如果失败(如果系统得到适当保护,则应该如此),侦听器将停止接收消息。
通常的建议是总是指定一个回退队列,要么让类使用它,要么编写应用程序来使用它。
请参阅 MQAPI 参考中的 Usage Notes for MQGET 和 .Net 类参考中的 MQGetMessageOptions.NET 页面。
【讨论】:
您可能想查看MQ Reporting Options。
到期、到达确认和交付确认可以由接收队列管理器通过响应队列请求并发送回发送应用程序。
肯定和否定确认也可以由接收应用程序生成,前提是它们使用消息描述符中的相关报告属性。
异常可以由传输链中的任何队列管理器请求并通过响应队列发送回发送应用程序或由接收应用程序生成。
【讨论】:
COMMIT/ROLLBACK 处理中执行确认,则Session.getAcknowledgeMode 方法将返回Session.SESSION_TRANSACTED。这完全符合 OP 的要求,即根据处理结果以原子方式使用或回滚消息。 COA 与消息消费无关,COD 与 GET 不在同一个 UOW 中,因此不符合任何人书中的 OP 要求。
1 使用 MQC.MQGMO_SYNCPOINT 读取消息,
2 处理它
3 调用 MQQueueManager.Commit()
如果 Commit() 没有被显式或隐式调用(例如抛出异常),所有已出队的消息都将重新入队。
【讨论】: