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