Spring DefaultMessageListenerContainer, ActiveMQ и повторная доставка сообщений - PullRequest
2 голосов
/ 02 февраля 2010

, если я использую DefaultMessageListenerContainer из Spring для получения сообщений JMS, я не получаю сообщения JMS, которые доставляются повторно, даже если для sessionAcknowledgeMode установлено значение 2.

В случае RuntimeException в onMessage() моего JavaBean сообщение не подтверждается провайдером JMS ( ActiveMQ ), оно остается в очереди в очереди. Но оно никогда не доставляется, что, по-моему, связано с тем, что Spring никогда не вызывает session.recover(), что, согласно документации ActiveMQ , требуется для повторной доставки.

Может ли кто-нибудь подсказать мне, как настроить DefaultMessageListenerContainer для вызова session.recover() в случае RuntimeExceptions?

С уважением,
Martin

1 Ответ

3 голосов
/ 03 февраля 2010

Вы указываете, что используете sessionAcknowledgeMode 2, который является Session.CLIENT_ACKNOWLEDGE. Следующее утверждение взято непосредственно из Javadocs AbstractMessageListenerContainer :

  • «CLIENT_ACKNOWLEDGE»: автоматическое подтверждение сообщения после успешного выполнения слушателя; возврат не производится в случае исключения.

Таким образом, проблема не в Spring DMLC, а в его способности вызывать Session.recover () при возникновении исключения времени выполнения. Возможно ли для вас использовать метод try / catch в методе onMessage () вашего слушателя для обработки исключений времени выполнения, вызывая Session.recover () самостоятельно?

Обновление:

Вы хорошо оценили шаблонный код. Он разбрызгивается во многих местах и ​​требует рефакторинга. Разве вы не можете абстрагировать такой код? Это общее решение. Создание абстрактного родительского класса с методом, который содержит try / catch с соответствующей обработкой, должно помочь. Затем просто расширьте родительский класс, чтобы реализовать столько пользовательских процессоров, сколько необходимо. Вы даже можете затем соединить процессоры соответствующим образом, используя контекст приложения Spring.

У меня никогда не было проблем с добавлением кода Spring в приложение, потому что оно работает где угодно. Это было важно для меня, когда я начал использовать Spring. Он не специфичен для какого-либо отдельного сервера приложений или контейнера сервлетов, поэтому я не зацикливаюсь на Spring с помощью Spring, как если бы я импортировал com.ibm или com.oracle в исходный код. Фактически, я использовал API Spring JMS с одной MOM и переключился на другую MOM, не меняя ничего, кроме определения фабрики соединений JMS.

...