Поведение подтверждения Spring JMS с TIBCO EMS EXPLICIT_CLIENT_DUPS_OK_ACKNOWLEDGE

Я использую Spring JMS с очередью / темой TIBCO EMS для своего приложения весенней загрузки. Очередь TIBCO EMS настраивается с помощью EXPLICIT_CLIENT_DUPS_OK_ACKNOWLEDGE. В моем коде я не устанавливаю режим подтверждения, поэтому предполагаю, что spring примет значение AUTO_ACKNOWLEDGE по умолчанию. Поведение, которое я замечаю в моем методе прослушивателя onMessage, заключается в том, что если приложение успешно обрабатывает сообщение, повторная доставка того же сообщения отсутствует. А если приложение генерирует исключение RuntimeException, происходит повторная доставка того же сообщения. Код также имеет для setSessionTranshibited значение true с помощью DefaultJmsListenerContainerFactory. В этом сценарии пружина действительно подтверждает сообщение от моего имени или код должен установить message.acknowledge ().


person Albin    schedule 01.02.2021    source источник


Ответы (1)


См. Javadocs для Session. Auto означает, что библиотека поставщика автоматически подтверждает сообщение, когда consumer.receive() возвращает его или consumer.messsageListener() завершает работу.

С SimpleMessageListenerContainer ваш слушатель вызывается непосредственно Consumer провайдера, поэтому сообщения не будут автоматически подтверждаться, пока ваш слушатель не завершит нормальный выход.

Вместо этого DirectMessageListenerContainer вызывает receive() и вызывает вашего слушателя в своем собственном потоке. Следовательно, нам нужны транзакции для отката подтверждения после возникновения исключения.

person Gary Russell    schedule 01.02.2021
comment
Я использую DefaultMessageListenerContainer. В javadoc я вижу, что это упомянуто ниже. Обратите внимание, что для режима AUTO_ACKNOWLEDGE по умолчанию этот контейнер применяет автоматическое подтверждение сообщения перед выполнением слушателя без повторной доставки в случае исключения. Но поведение, которое я наблюдаю, как я уже упоминал в вопросе, отличается от того, что указано в javadoc - person Albin; 01.02.2021
comment
Непонятно, что вы имеете в виду; в вашем вопросе вы сказали, что используете DMLC и setSessionTransacted=true; это вызовет повторную доставку, если слушатель выдаст исключение (как вы говорите, это происходит). Сообщение подтверждается внутри транзакции, и транзакция откатывается, следовательно, подтверждение также откатывается, и сообщение повторно ставится в очередь. - person Gary Russell; 01.02.2021
comment
то, что я говорил, это то, что javadoc сообщает, что контейнер применяет автоматическое подтверждение сообщения «до» выполнения слушателя, но для меня поведение после выполнения. То же, что вы сказали, но javadoc сообщает, что это было раньше. Вот в чем мое замешательство - person Albin; 05.02.2021
comment
Документ правильный; сообщение действительно подтверждается перед вызовом слушателя (до возврата receive()). Просто из-за того, что слушатель выдает исключение, транзакция откатывается (включая уже отправленное подтверждение), поэтому сообщение повторно ставится в очередь. Если вы не используете транзакции, сообщение будет потеряно. - person Gary Russell; 05.02.2021