[英]JMS processing same message in 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
:
:
当您将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事务被回滚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.