【发布时间】:2010-12-12 18:55:12
【问题描述】:
当我使用消息监听器时如何确认消息?
当我尝试在消息侦听器中进行确认时收到以下错误。
A synchronous method call is not permitted when a session is being used asynchronously: 'acknowledge'
【问题讨论】:
当我使用消息监听器时如何确认消息?
当我尝试在消息侦听器中进行确认时收到以下错误。
A synchronous method call is not permitted when a session is being used asynchronously: 'acknowledge'
【问题讨论】:
为后代放大第一个答案:OP 可能创建了他的会话,确认模式设置为 Session.AUTO_ACKNOWLEDGE,这意味着提供者在消息在连接上传递(用于同步传递)或之后自动确认消息您的 MessageListener#onMessage() 被调用(用于异步传递)。
他得到了异常,因为他对 Message#acknowledge() 的显式调用在此模式下无效。正如 Buhake Sindi 指出的那样,如果您希望手动确认消息,则必须在设置将创建 MessageConsumer 的会话时选择 Session.CLIENT_ACKNOWLEDGE。然后,每次调用 Message#acknowledge() 时,当前消息以及传递给此会话/消费者的任何其他已传递但未确认的消息都会被确认回代理。
【讨论】:
使用会话外的 getAcknowledgeMode() 方法检查您的会话是否需要确认,如果确实需要,则只需在消息本身上调用确认() 方法
【讨论】:
这是队列会话的示例
session = connection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
只有当
if (session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE) //
那我们可以吗
message.acknowledge();
在此处查看 Message 类 (http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html)
【讨论】:
您说的是Message.acknowledge() 中的JMS 消息确认?
这个错误似乎有点奇怪。如果您不使用事务或自动确认,我认为您需要调用该方法。如果你在做异步监听,除了 onMessage() 方法,你在哪里做呢?
此调用是否在获得 onMessage() 调用的同一线程中完成?换句话说,在 onMessage() 中还是在从 onMessage() 调用的某个方法中?如果不是,那么您就违反了 JMS 的线程规则。会话和生产者/消费者以及任何更往下的东西(如消息)都不是线程安全的。您需要确保您没有从多个线程中触摸它们。如果您在 onMessage() 调用中,并且您以某种方式安排另一个线程来执行该 Message.acknowledge() 调用,那么由于线程问题,您应该失败。如果是这样,请将该回调移回运行 onMessage() 的同一线程上。
【讨论】:
根据定义,异步消息不应在协议级别得到确认。如果您需要确认,您必须将其构建到您的应用程序中,此时的问题是您为什么不使用同步方案。
【讨论】: