MQ消息回滚

问题描述:

我想从Java中的MQ队列中读取消息,并且在处理异常时需要回滚时我有点困惑。MQ消息回滚

我有一个阅读器类,在循环中运行并查找消息。当我初始化阅读器时,它会创建一个连接和一个会话。然后,当要在循环中读取消息时,它会创建一个MQQueueMQQueueReceiver。这工作正常,我得到一个JMSMessage队列,然后交给另一个线程工作。如果工作线程失败,我想将该消息放回到队列中(这样它会被群集中的其他节点重试)。

我的问题是,我该如何回滚?我注意到在MQQueueSession类中有一个rollback()方法。但我正在重复使用同一个会话来处理所有消息。我是否明白应该为每条消息创建一个新的会话,而不是一遍又一遍地重复使用同一个消息?

这对我来说很直观。

此外,会话使用connection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);创建。我是否应该使用另一个标志,而不是CLIENT_ACKNOWLEDGE

您应该使用Session.SESSION_TRANSACTED标志和Session.commit/Sessiuon.rollback提交/回滚在当前事务中进行

+0

完美。谢谢 – mprivat

注意所有消息的JMS 1.1规范会话定义为:

会议 - 在规格上发送和接收消息

后来一个单线程上下文,它说:

限制对会话的并发访问有两个原因。首先,会话是支持事务的JMS实体。很难实现多线程的事务,这是 。其次,会话支持异步消息消费。重要的是,JMS不要求用于异步消息的客户端代码能够处理多个并发的消息。另外,如果一个会话已经建立了多个异步使用者,重要的是客户端并不是强制 来处理这些单独使用者同时执行的情况。这些限制使JMS更易于用于典型的 客户端。更复杂的客户可以通过使用多个会话来获得他们想要的并发性。

所以,不,你不需要每个消息一个会话。但是,即使您已将这些消息交给其他线程,并且此行为符合规范,在会话期间生成或使用的所有消息也会被提交或回滚到一起,即

使用Evgeniy描述的事务会话和COMMIT/ROLLBACK,但也要注意保持同一会话范围内的消息都在同一工作单元内。