gpt4 book ai didi

java - JMS 监听器中出现异常时重新传递 JMS 消息

转载 作者:搜寻专家 更新时间:2023-11-01 02:43:04 25 4
gpt4 key购买 nike

org.springframework.jms.listener.AbstractMessageListenerContainer 的 Javadoc 指出,如果

"sessionAcknowledgeMode" set to "CLIENT_ACKNOWLEDGE": Automatic message acknowledgment after successful listener execution; no redelivery in case of exception thrown.

我猜,“在抛出异常的情况下不重新传递”意味着,即使在 jms 监听器中抛出异常,也不会重新传递该消息(因此,我猜,它会被确认)。但是,好吧,监听器抛出的异常意味着对其的调用不成功,并且由于没有确认,应该重新传递。

问题是:
如果在 jms 监听器中抛出异常,消息确认实际上应该发生什么?

真正发生了什么,可以从这个堆栈跟踪中看到:

at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:98)
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:66)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:660)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:620)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:591)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:308)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:246)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1142)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1134)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1031)

堆栈跟踪的第 5 行特别令人感兴趣。那里的代码基本上意味着,(大部分)从监听器抛出的任何异常都将绕过 org.springframework.jms.listener.AbstractMessageListenerContainer#commitIfNecessary 中完成的确认。
没关系,但是“抛出异常时不重新传送”是什么意思?

附加信息:
spring-jms:4.1.2

<bean id="someListenerContainerFactory" class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="concurrency" value="1-10"/>
<property name="sessionAcknowledgeMode">
<util:constant static-field="javax.jms.Session.CLIENT_ACKNOWLEDGE"/>
</property>
</bean>

最佳答案

这取决于您使用的监听器容器;使用 AUTO ack 模式时,SimpleMessageListenerContainer 会在监听器返回后进行确认(即传统的 JMS MessageListener)。 DefaultMessageListenerContainer 在调用监听器之前进行确认,因此您需要 acknowledgeMode="transacted" 来防止消息丢失。

这方面的 javadoc 有点误导,已被 improved recently .

使用 CLIENT_ACKNOWLEDGE,您可以自己进行确认。该文档只是意味着您是经纪人的心血来潮。根据 JMS 消息 javadoc:

Messages that have been received but not acknowledged may be redelivered

根据我的经验,最好使用带有 SMLC 的自动确认和带有 DMLC 的交易。

关于java - JMS 监听器中出现异常时重新传递 JMS 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29413784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com