JMS обрабатывает то же сообщение в onMessage()

У меня есть JMS 2.0 MessageListener, который, кажется, время от времени повторно обрабатывает сообщения, даже если они были успешно обработаны (подтверждены через журнал). Я подозреваю, что необходимо выполнить session.commit(), но я не уверен, потому что в подавляющем большинстве случаев сообщения НЕ повторяются. Насколько я понимаю, по умолчанию используется AUTO_ACKNOWLEDGE, но опять же, я не совсем уверен, как это работает для SessionAwareMessageListener.

Соответствующий раздел spring.xml выглядит примерно так

<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        :
        :
        <property name="messageListener" ref="myMessageListener" />
        <property name="maxConcurrentConsumers" value="1" />
        <property name="receiveTimeout" value="5000" />
        <property name="sessionTransacted" value="true" />
    </bean>

Реализация MessageListener выглядит следующим образом

public class MyMessageListener implements SessionAwareMessageListener {

   // All spring autowired objects
   :
   :
   @Override
   public void onMessage(Message message, Session session)
   {
     logger.debug("JMSMessage ID : " + message.JMSMessageId, "Entering onMessage() ...");
     logger.debug("JMSMessage ID : " + message.JMSMessageId, "Retry Count : " + message.getIntProperty("JMSXDeliveryCount"));
     try
     {
     
     }
     catch(JMSException e)
     {
        // Log something 
        throw new RuntimeException(e);
     }
     catch(Exception ex)
     {
        if(certain types of exceptions)
        {
          session.rollback();
          System.Exit(1);
        }
        
        throw new RuntimeException(ex);

     }
     // THE FOLLOWING IS THE LAST LINE IN onMessage()
     logger.debug("JMSMessage ID : " + message.JMSMessageId,"Completed successfully !");

   }


}

Итак, почти все сообщения, которые я сейчас вижу, имеют это в журналах

:
JMSMessage Id : 1234, Entering onMessage()
JMSMessage Id : 1234, Retry count : 1
:
JmsMessage Id : 1234, Completed successfully!
JmsMessage Id : 3344, Entering onMessage() // New message taken up for processing.
JMSMessage Id : 3344, Retry count : 1

Проблема в том, что время от времени (после тысяч сообщений) я вижу это в журналах

:
JMSMessage Id : 5566, Entering onMessage()
JMSMessage Id : 5566, Retry count : 1
:
JmsMessage Id : 5566, Completed successfully!
JMSMessage Id : 5566, Entering onMessage() // WHY IS JMS PROCESSING THE SAME MESSAGE (MESSAGEID : 5566) AGAIN ?
JMSMessage Id : 5566, Retry count : 2 
:
:

1 ответ

Когда у тебя есть sessionTransacted установлено значение true, режим подтверждения игнорируется, есть даже специальное значение, которое может быть установлено для обозначения того, что он не используется, из других примеров я вижу это:

<property name="sessionAcknowledgeModeName" value="SESSION_TRANSACTED"/>

Согласно ответу Гэри Рассела на вопрос о переполнении стека, потребление сообщений Spring DMLC: auto_ack vs Transhibited Session, если у вас естьsessionTransacted Если для DMLC установлено значение true, сеанс фиксируется DMLC после вызова слушателя, если слушатель выдает исключение, транзакция откатывается.

Другие вопросы по тегам