【问题标题】:Why are JMS messages acknowledged automatically为什么 JMS 消息会自动确认
【发布时间】:2016-03-03 13:30:00
【问题描述】:

即使确认模式设置为CLIENT_ACKNOWLEDGE,为什么在onMessage() 侦听器方法返回后仍确认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的意思是我需要手动确认消息?

有什么想法吗?

谢谢,米凯尔

【问题讨论】:

    标签: java jms spring-jms


    【解决方案1】:

    在这种情况下,消息侦听器容器是客户端,而不是您的侦听器。

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

    【讨论】:

    • 有趣,所以如果我想使用带有监听器的异步模型,唯一的选择是在 onMessage 方法中抛出异常,这样消息就不会被确认?
    • 我不确定你的意思;客户端确认旨在推迟确认,但最终必须确认;消息在确认之前保持“未确认”状态;如果连接丢失,它们将被重新排队。抛出异常将导致消息被丢弃或重新排队,具体取决于您是否使用事务、确认模式和/或您使用的容器类型。使用 SimpleMessageListenerContainer 和 AUTO,消息将被重新排队;使用 DefaultMessageListenerContainer 和 AUTO,消息将被丢弃,除非会话已被处理。
    • 我认为 CLIENT_ACK 表示在成功处理后确认消息是消费者的责任。如果消费者在 onMessage 方法中没有对消息进行确认,则消息将不会被确认并因此重新排队。
    • 只有在会话关闭时才会重新排队;经纪人不知道您何时完成或您是否使用批量确认;见Message.acknowledge()
    猜你喜欢
    • 1970-01-01
    • 2012-01-13
    • 2010-12-12
    • 1970-01-01
    • 2014-05-06
    • 2011-03-30
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    相关资源
    最近更新 更多