简体   繁体   English

JMS 在 onMessage() 中处理相同的消息

[英]JMS processing same message in onMessage()

I have a JMS 2.0 MessageListener which seems to be sporadically reprocessing messages even when they have been successfully processed (confirmed via a log).我有一个 JMS 2.0 MessageListener,即使消息已成功处理(通过日志确认),它似乎也会偶尔重新处理消息。 I am suspecting that a session.commit() needs to be done but I am unsure because in a vast majority of cases, the messages are NOT retried.我怀疑需要完成 session.commit() 但我不确定,因为在绝大多数情况下,消息不会重试。 From what I understand, AUTO_ACKNOWLEDGE is the default but again, I am not so sure how it works for SessionAwareMessageListener.据我了解,AUTO_ACKNOWLEDGE 是默认设置,但我不太确定它对 SessionAwareMessageListener 是如何工作的。

The relevant spring.xml section looks something like this相关的 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 implementation is as follows 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 !");

   }


}

So, almost all the messages that I see now have this in the logs所以,我现在看到的几乎所有消息都在日志中

:
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

The problem is that once in a while (after thousands of messages), I see this in the logs问题是偶尔(在数千条消息之后),我会在日志中看到这个

:
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 
:
:

When you have sessionTransacted set to true acknowledge mode is ignored, there is even a special value that can be set to denote that it is not being used, from other examples I see this:当您将sessionTransacted设置为 true 确认模式被忽略时,甚至可以设置一个特殊值来表示它没有被使用,从其他示例中我看到了这一点:

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

According to Gary Russell's answer to the stackoverflow question Spring DMLC message consumption: auto_ack vs Transacted Session , if you have sessionTransacted set to true with a DMLC, the session is committed by the DMLC after the listener is called, if the listener throws an exception the transaction is rolled back. According to Gary Russell's answer to the stackoverflow question Spring DMLC message consumption: auto_ack vs Transacted Session , if you have sessionTransacted set to true with a DMLC, the session is committed by the DMLC after the listener is called, if the listener throws an exception the事务被回滚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM