MQ消息回滚

时间:2013-04-18 13:59:47

标签: java jms mq

我正在尝试用Java中的MQ队列读取消息,当处理异常时回滚时,我对流程有点困惑。

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

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

这对我来说很直观。

此会话也是使用connection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);创建的。我应该使用CLIENT_ACKNOWLEDGE以外的其他标志吗?

2 个答案:

答案 0 :(得分:1)

您应该使用Session.SESSION_TRANSACTED标志和Session.commit / Sessiuon.rollback来提交/回滚当前事务中完成的所有消息

答案 1 :(得分:1)

请注意,JMS 1.1规范将会话定义为:

  

Session - 用于发送和接收消息的单线程上下文

后来在规范中说:

  

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

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

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