2010-04-12 7 views
3

У нас есть контейнер прослушивателя сообщений JMS Spring для приема асинхронных сообщений. Использование DefaultMessageListenerContainer и в режиме sessionTransacted. Я понимаю, что в режиме sessionTransacted в случае исключения сообщение будет возвращено в очередь. Но как я могу удостовериться, что сообщение не будет удалено из очереди, даже если ресивер (который выбрал сообщение) сработает или просто работает компьютер?Сохранение сообщений в очереди при сбое получателя

Сначала я думал, что режим подтверждения CLIENT_ACKNOWLEDGE должен спасти меня, но apparently это не тот случай, Spring звонки .знание() независимо от того, что.

Итак, вот мой вопрос, как я могу гарантировать доставку? Использование настраиваемого MessageListenerContainer? Использование диспетчера транзакций?

ответ

1

Используйте транзакционный сеанс и укажите успешную обработку сообщений, вызвав метод класса commit().

Проверьте конфигурацию конфигурации 19.4.5. Processing messages within transactions. (вы можете использовать DefaultMessageListenerContainer). В зависимости от того, что вы делаете с сообщениями, вам может понадобиться менеджер транзакций JTA.

-1

или вы можете использовать Session.AUTO_ACKNOWLEDGE с nontransacted сессии см цитату ниже от этого article

сообщение является автоматически признается, когда его успешно возвращается от метода приема(). Если , приемник использует интерфейс MessageListener , сообщение автоматически подтверждается, когда успешно возвращает из метода 0MMESAGE() . Если произошел сбой при выполнении метода receive() или метода onMessage(), сообщение будет автоматически повторно отправлено. Поставщик JMS тщательно управляет сообщением и возвращает семантику доставки только один раз.

+0

-1, поскольку вывод, сделанный из этого документа, неверен. Да, есть redelivery, если вызов receive() или onMessage() завершается неудачно, но это не означает, что у получателя есть шанс что-то сделать с сообщением. Если ресивер сработает в этот момент, сообщение безвозвратно потеряно, чего пытается избежать OP.Однако использование транзакционного сеанса и явных вызовов фиксации, как описано в другом ответе, предотвращает такую ​​потерю сообщений, если сбой приемника. –

+0

Итак, в двух словах статья вводит в заблуждение? Что означает крах? если метод onMessage не возвращается из-за сбоя, не будет ли сообщение повторно отправлено? – soody

+0

Я не говорю, что статья вводит в заблуждение, просто она не относится к исходному вопросу. Все ошибки, описанные в цитате статьи, происходят до того, как сообщение возвращается в приложение. OP хотел отложить подтверждение сообщения до тех пор, пока сообщение не будет возвращено, и приложение не обработало его, как предполагается, должен предоставить CLIENT_ACKNOWLEDGE. Установка Session.AUTO_ACKNOWLEDGE фактически обеспечивает соблюдение поведения, которое пытается предотвратить OP. –

0

Слушатель сообщения Spring с режимом Client_Acknowledge подтвердит сообщение, когда клиент вызывает message.acknowledge().

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

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

Слушатель сообщения Spring позволяет только исключить исключение JMS из прослушивания onMessage. Захват пользовательского исключения и исключение исключения JMS из прослушивателя (после регистрации ошибки для последующего использования) позволит вам повторно отправить сообщение.

Смежные вопросы