简体   繁体   English

JMS确认异步消息

[英]JMS Acknowledge Asynchronous Message

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'

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? 该调用是否在与onMessage()调用相同的线程中完成? In other words, in onMessage() or in some method called from onMessage()? 换句话说,是在onMessage()还是从onMessage()调用的某些方法中? If not, you're breaking the thread rules of JMS. 否则,您将违反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. 如果您处于onMessage()调用的中间,并且以某种方式安排另一个线程来执行该Message.acknowledge()调用,则由于线程问题,您理应失败。 If so, move that call back on the same thread that onMessage() is running in. 如果是这样,则将该调用移回与运行onMessage()的线程相同的线程。

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

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. 他之所以例外,是因为他对Message#acknowledge()的显式调用在此模式下无效。 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. 正如Buhake Sindi指出的那样,如果您希望手动确认消息,则在设置要从其创建MessageConsumer的会话时,必须选择Session.CLIENT_ACKNOWLEDGE。 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()时,当前消息以及传递给该会话/消费者的任何其他已传递但未确认的消息都将被确认回给代理。

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. 如果要确认,则必须将其构建到应用程序中,此时的问题是为什么不使用同步方案。

通过在会话外使用getAcknowledgeMode()方法来检查会话是否需要确认,如果确实需要,则只需在消息本身上调用accept()方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM