在测试使用 IBM Websphere MQ 的应用程序时,我在 MQ 中提交消息时遇到了问题。
基本上有一个批次从 Oracle DB 读取并处理信息并写入队列。
同一个批处理应用程序的多个实例可以使用某些参数同时运行,因此数据库记录永远不会重叠并且始终不同,但它们都将消息写入同一个队列。
两个实例在生成 1000 条消息并放入队列后提交消息。
队列管理器的最大未提交大小为 1000。
第一次运行: QM的默认持久性:持久 最大未提交消息数:1000
同时运行两个实例时遇到错误。
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2053' ('MQRC_Q_FULL').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
第二次运行: QM默认持久化:非持久化 最大未提交消息数:1000
两个批次均成功运行。
第三次运行: QM的默认持久性:持久 最大未提交消息数:10000
两个批次均成功运行。
我想知道为什么第二次运行成功,即使最大未提交消息数为 1000。
IBM MQ 事务内部如何工作?是由于MQ对持久化消息使用的缓存机制造成的吗?或者由于非持久消息的速度快而从未遇到过错误?
我认为这种行为最可能的原因是,您没有在代码中的放置消息选项中指定 MQPMO_SYNCPOINT,而是依赖隐式同步点选项以事务方式放置消息:
https://www.ibm.com/docs/en/ibm-mq/9.3?topic=multiplatforms-implicit-syncpoint
但是如果没有看到您的代码,我们无法确定。
我认为这是对持久消息和非持久消息之间差异的一个很好的描述:
https://www.ibm.com/support/pages/message-persistence-faqs
但我认为最重要的区别是持久性消息在 QM 重新启动后仍然存在,而非持久性消息在重新启动时会被删除。