JMS подтверждает асинхронное сообщение

Как мне подтвердить сообщение, когда я использую прослушиватель сообщений?

Я получаю следующую ошибку, когда пытаюсь выполнить подтверждение в моем прослушивателе сообщений.

A synchronous method call is not permitted when a session is being used asynchronously: 'acknowledge'

person x1a0    schedule 03.11.2009    source источник


Ответы (5)


Вы говорите о подтверждении сообщений JMS, как в Message.acknowledge()?

Эта ошибка кажется немного странной. Если вы не используете транзакции или автоматическое подтверждение, я думаю, вам нужно вызвать этот метод. И если вы выполняете асинхронное прослушивание, где вы это делаете, кроме метода onMessage()?

Выполняется ли этот вызов в том же потоке, который получил вызов onMessage()? Другими словами, в onMessage() или в каком-то методе, вызываемом из onMessage()? Если нет, вы нарушаете правила потоков JMS. Сессии и производители/потребители и все, что ниже (например, сообщения), не является потокобезопасным. Вы должны убедиться, что вы не касаетесь их из нескольких потоков. Если вы находитесь в середине вызова onMessage() и каким-то образом организуете другой поток для выполнения этого вызова Message.acknowledge(), вы заслуживаете неудачи из-за проблемы с потоком. Если это так, переместите этот вызов обратно в тот же поток, в котором выполняется onMessage().

person John M    schedule 09.11.2009

Это пример сеанса очереди

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)

person Buhake Sindi    schedule 19.03.2010

Чтобы немного расширить первый ответ для потомков: ОП, вероятно, создал свой сеанс с режимом подтверждения, установленным на Session.AUTO_ACKNOWLEDGE, что означает, что провайдер автоматически подтверждает сообщения по мере их доставки по соединению (для синхронной доставки) или после вашего MessageListener# onMessage() вызывается (для асинхронной доставки).

Он получил исключение, потому что его явный вызов Message#acknowledge() недействителен в этом режиме. Как указывает Бухаке Синди, если вы хотите подтверждать сообщения вручную, вы должны выбрать Session.CLIENT_ACKNOWLEDGE при настройке сеанса, из которого будет создан MessageConsumer. Затем каждый раз, когда вы вызываете Message#acknowledge(), текущее сообщение вместе с любыми другими доставленными, но неподтвержденными сообщениями, доставленными этому сеансу/потребителю, будет подтверждено брокеру.

person Larry McQueary    schedule 20.07.2014

Асинхронное сообщение по определению не должно быть подтверждено на уровне протокола. Если вам нужно подтверждение, вы должны встроить его в свое приложение, и в этот момент возникает вопрос, почему вы не используете синхронную схему.

person Jim Garrison    schedule 03.11.2009

Проверьте, требует ли ваш сеанс подтверждения, используя метод getAcknowledgeMode() вне сеанса, если это так, то просто вызовите метод подтверждения() в самом сообщении.

person Billy    schedule 17.04.2010