带有 TIBCO EMS EXPLICIT_CLIENT_DUPS_OK_ACKNOWLEDGE 的 Spring JMS 确认行为

问题描述

我正在将 Spring JMS 与 TIBCO EMS 队列/主题用于我的 Spring Boot 应用程序。 TIBCO EMS 队列是使用 EXPLICIT_CLIENT_DUPS_OK_ACKNowLEDGE 设置的。在我的代码中,我没有设置确认模式,所以我假设 spring 将采用它的认 AUTO_ACKNowLEDGE。我在监听器 onMessage 方法中注意到的行为是,如果应用程序成功处理了消息,则不会重新传递相同的消息 如果应用程序抛出 RuntimeException,则会重新传递相同的消息。该代码还使用 DefaultJmsListenerContainerFactory 将 setSessionTransacted 设置为 true。在这种情况下,是 spring 实际代表我确认消息还是代码需要设置 message.ackNowledge()。

解决方法

请参阅 Session 的 javadoc。 Auto 表示提供程序库在 consumer.receive() 返回消息或 consumer.messsageListener() 退出时自动确认消息。

使用 SimpleMessageListenerContainer,您的侦听器由提供者的使用者直接调用,因此在您的侦听器正常退出之前不会自动确认消息。

DirectMessageListenerContainer 调用 receive() 并在其自己的线程上调用您的侦听器。因此,我们需要事务在抛出异常后回滚 ack。