java JMS 确认异步消息
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1669746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JMS Acknowledge Asynchronous Message
提问by x1a0
How do I acknowledge a message when I am using a message listener?
使用消息侦听器时如何确认消息?
I get the following error when I try to do an acknowledge in my message listener.
当我尝试在消息侦听器中进行确认时,出现以下错误。
A synchronous method call is not permitted when a session is being used asynchronously: 'acknowledge'
回答by John M
You're talking about JMS messages acknowledgement as in Message.acknowledge()?
您是在讨论Message.acknowledge() 中的JMS 消息确认吗?
That error seems a little odd. If you aren't using transactions or auto-acknowledge, I'd think you need to call that method. And if you're doing async listening, where are you doing to do it aside from the onMessage() method?
这个错误似乎有点奇怪。如果您不使用事务或自动确认,我认为您需要调用该方法。如果您正在进行异步侦听,除了 onMessage() 方法之外,您还在哪里做呢?
Is this call being done in the same thread that got the onMessage() call? In other words, in onMessage() or in some method called from onMessage()? If not, you're breaking the thread rules of JMS. Sessions and producers/consumers and anything further down (like Messages) aren't thread safe. You need to make sure you're not touching them from multiple threads. If you're in the middle of an onMessage() call and you somehow arrange another thread to do that Message.acknowledge() call, you deserve to fail because of the thread problem. If so, move that call back on the same thread that onMessage() is running in.
这个调用是在获得 onMessage() 调用的同一个线程中完成的吗?换句话说,在 onMessage() 或从 onMessage() 调用的某些方法中?如果没有,您就违反了 JMS 的线程规则。会话和生产者/消费者以及任何更深的东西(如消息)都不是线程安全的。你需要确保你没有从多个线程接触它们。如果您正在 onMessage() 调用中,并且以某种方式安排另一个线程来执行 Message.acknowledge() 调用,则由于线程问题,您应该失败。如果是这样,请将该调用移回运行 onMessage() 的同一线程。
回答by Buhake Sindi
This is an example for Queue Session
这是队列会话的示例
session = connection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
Only if
除非
if (session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE) //
Then can we have
那么我们可以有
message.acknowledge();
Check the Message class here (http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html)
在此处检查 Message 类(http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html)
回答by Larry McQueary
To amplify the first answer a bit for posterity: The OP probably created his session with acknowledgement mode set to Session.AUTO_ACKNOWLEDGE, which means the provider automatically acknowledges the messages as they are delivered on the connection (for synchronous delivery) or after your MessageListener#onMessage() is called (for asynchronous delivery).
为后代稍微放大第一个答案:OP 可能创建了他的会话,确认模式设置为 Session.AUTO_ACKNOWLEDGE,这意味着提供者会在消息在连接上传递(用于同步传递)或在您的 MessageListener# 之后自动确认它们onMessage() 被调用(用于异步传递)。
He got the exception because his explicit call to Message#acknowledge() is not valid in this mode. As Buhake Sindi points out, if you wish to manually acknowledge messages, you must choose Session.CLIENT_ACKNOWLEDGE when you set up the session from which the MessageConsumer will be created. Then, each time you call Message#acknowledge(), the current message, along with any other delivered but unacknowledged messages delivered to this session/consumer, will be acknowledged back to the broker.
他得到了异常,因为他对 Message#acknowledge() 的显式调用在这种模式下无效。正如 Buhake Sindi 指出的那样,如果您希望手动确认消息,则必须在设置将创建 MessageConsumer 的会话时选择 Session.CLIENT_ACKNOWLEDGE。然后,每次您调用 Message#acknowledge() 时,当前消息以及任何其他已交付但未确认的消息将被确认返回给代理。
回答by Billy
Check to see if your session requires acknowledgement by using getAcknowledgeMode() method off the session, if it does then just call the acknowledge() method on the message itself
通过使用 getAcknowledgeMode() 方法关闭会话检查您的会话是否需要确认,如果需要,则只需在消息本身上调用acknowledge() 方法
回答by Jim Garrison
An asynchronous message, by definition, is not expected to be acknowledged at the protocol level. If you want an acknowledgement you must build it into your application, at which point the questions is why aren't you using a synchronous scheme.
根据定义,异步消息不应在协议级别得到确认。如果您想要确认,您必须将其构建到您的应用程序中,此时问题是您为什么不使用同步方案。

