JMS Acknowledge Asynchronous Message
How do I acknowledge a messa开发者_JAVA百科ge 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'
You're talking about JMS messages acknowledgement as in Message.acknowledge()?
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?
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.
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)
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).
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.
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.
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
精彩评论