【发布时间】:2025-12-14 14:20:22
【问题描述】:
我确实有以下(多线程)进程:
- 浏览 MQ 队列(带锁)并获取下一条可用消息
- 用它做一些可能失败也可能不会失败的事情
- 一个。如果成功,从队列中删除消息并重新开始,或者 b.如果不成功,请在队列中留言
我的问题源于我的应用程序可能在第 2 步和第 3 步之间意外死机,然后应用程序在重新启动时会产生重复的消息。
有没有办法在队列中将消息标记为“脏”或“正在处理”(在读取消息时或读取后),即使应用程序重新启动,该标记仍然存在?
我尝试使用 MQ 提供的标记,但它们无法在重新启动后继续存在。另一种可能性是将消息移动到“处理”队列,成功时将其删除或失败时将其移回源队列,但这需要第二个队列并且不再是微不足道的代码。
粗略的代码示例:
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQConstants.MQGMO_BROWSE_FIRST | MQConstants.MQGMO_LOCK;
MQMessage message = new MQMessage();
message.correlationId = MQC.MQCI_NONE;
message.messageId = MQC.MQMI_NONE;
queue.get(message, gmo);
boolean success = processMessage(message);
// Application gets killed here after successful message processing.
// Produces duplicate after restart.
if (success) {
MQGetMessageOptions gmo2 = new MQGetMessageOptions();
gmo2.options = MQConstants.MQGMO_MSG_UNDER_CURSOR;
queue.get(new MQMessage(), gmo2);
}
基本上,我想实现这个:
- 从队列中无损获取消息(仅当未标记为“处理中”时)
- 在队列中将消息标记为“处理中”
- 处理消息(包括发送到某个目的地)
- 如果成功从队列中删除,否则删除队列上的“处理”状态
如果应用程序在成功的第三步“处理消息”后立即终止,则该消息将被标记为“处理中”并且不会再次被处理(因为它可能已经被处理了)。
注意:我不希望这个过程对消息处理有任何了解(除了成功之外)。
【问题讨论】:
标签: ibm-mq