为什么自动确认JMS消息
问题描述:
为什么在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
意味着我需要手动确认消息?
有什么想法?
谢谢,迈克尔
答
在此背景下,该消息侦听容器是客户,而不是你的听众。
如果您希望手动确认(可能在收到大量消息后),请勿使用侦听器容器;您可以使用JmsTemplate.execute()
与SessionCallback
并创建自己的消费者。
有意思,所以如果我想与侦听器一起使用异步模型,唯一的选择是在onMessage方法内抛出异常,以便消息不被确认? –
我不确定你的意思;客户确认是为了推迟确认,但他们最终必须被确认;在确认之前,消息保持'未确认'状态;如果连接丢失,它们将被重新排队。抛出异常将导致邮件被删除或重新发送,具体取决于您使用的是事务,确认模式和/或您正在使用的容器类型。使用SimpleMessageListenerContainer和AUTO时,消息将被重新排序;使用DefaultMessageListenerContainer和AUTO,消息将被删除,除非会话被处理。 –
我认为CLIENT_ACK意味着消费者在成功处理后确认消息的责任。如果消费者不在onMessage方法内部回复消息,则该消息不会被确认并因此被重新排序。 –