2010-04-07 33 views
12

我使用Spring 2.5和实现MessageListener的自定义类。如果在我的onMessage()方法中引发JmsException,那么队列的状态会发生什么变化?当onMessage()抛出JMSException时,JMS队列上会发生什么?

在消息被调用的那一刻,消息是否被队列视为“传递”了?或者JmsException触发某种回滚,并且消息被重新输入到队列中?

在此先感谢!

回答

13

从JMS 1.1规范...

4.5.2异步传送

客户端可以注册一个实现用的MessageConsumer的JMS MessageListener接口的对象。当消息到达消费者时,提供者通过调用监听器的onMessage方法来传递它们。

侦听器可能抛出RuntimeException;但是,这被认为是客户端编程错误。行为良好的监听者应该捕获这些异常并尝试转移消息,导致他们转向某种形式的特定于应用程序的“不可处理的消息”目标。

侦听器抛出RuntimeException的结果取决于会话的确认模式。

  • AUTO_ACKNOWLEDGE或 DUPS_OK_ACKNOWLEDGE - 消息 将立即重新传递。 JMS提供商将 在 放弃之前重新传递相同消息的次数取决于提供程序。在这些情况下,将针对重新发送的消息 设置JMSRedelivered消息报头字段 。
  • CLIENT_ACKNOWLEDGE - 传递侦听器的下一条消息 。如果一个 客户端希望重新发送前一个 未确认消息,那么它必须手动恢复该会话。
  • 已处理会话 - 传递侦听器的下一条消息 。 客户端可以提交或回滚 会话(换句话说, RuntimeException不会自动回滚会话 )。

JMS提供程序应该标记客户端的消息侦听器正在抛出 RuntimeExceptions可能有故障。

+0

如果在onMessage中发生未处理的异常并且方法永不返回,会发生什么?是否有可能不会从队列中删除消息?这是否意味着(对于同步客户端)onMessage必须返回确认信息,以便可以从队列中删除消息? – bluelurker 2016-02-01 18:06:30

+0

@bluelurker - 我很困惑你的问题。 spec语言是关于允许RuntimeException从onMessage()方法传播出去的。如果您的方法通过抛出异常完成,那么这是“正常”返回的替代方法。所以我不明白“永不回头”的部分。它不会返回,而是通过传播一个异常来完成。 – 2016-02-11 19:55:46

+0

@JohnM从onMessage()方法,如果我抛出RunTimeException那么该消息将保持队列,并再次交付。再一次的消息将被抛出。它会再次交付。等等....我的理解是正确的吗?这是我在测试中看到的情况。 – 2017-06-04 10:07:29

相关问题