2016-03-03 98 views
0

为什么在onMessage()侦听器方法返回后,即使确认模式设置为CLIENT_ACKNOWLEDGE,JMS消息也得到确认?为什么自动确认JMS消息

如果你看一下在AbstractMessageListenerContainer类的commitIfNecessary方法,你可以看到如下:

protected void commitIfNecessary(Session session, Message message) throws JMSException { 
    // Commit session or acknowledge message. 
    if (session.getTransacted()) { 
     // Commit necessary - but avoid commit call within a JTA transaction. 
     if (isSessionLocallyTransacted(session)) { 
      // Transacted session created by this container -> commit. 
      JmsUtils.commitIfNecessary(session); 
     } 
    } else if (message != null && isClientAcknowledge(session)) { 
     message.acknowledge(); 
    } 
} 

调试后,我确认message.acknowledge()被调用。

我认为CLIENT_ACKNOWLEDGE意味着我需要手动确认消息?

有什么想法?

谢谢,迈克尔

回答

1

在此背景下,该消息侦听容器是客户,而不是你的听众。

如果您希望手动确认(可能在收到大量消息后),请勿使用侦听器容器;您可以使用JmsTemplate.execute()SessionCallback并创建自己的消费者。

+0

有意思,所以如果我想与侦听器一起使用异步模型,唯一的选择是在onMessage方法内抛出异常,以便消息不被确认? –

+0

我不确定你的意思;客户确认是为了推迟确认,但他们最终必须被确认;在确认之前,消息保持'未确认'状态;如果连接丢失,它们将被重新排队。抛出异常将导致邮件被删除或重新发送,具体取决于您使用的是事务,确认模式和/或您正在使用的容器类型。使用SimpleMessageListenerContainer和AUTO时,消息将被重新排序;使用DefaultMessageListenerContainer和AUTO,消息将被删除,除非会话被处理。 –

+0

我认为CLIENT_ACK意味着消费者在成功处理后确认消息的责任。如果消费者不在onMessage方法内部回复消息,则该消息不会被确认并因此被重新排序。 –