JMS侦听器中异常时java JMS消息的重新传递
Javadoc for org.springframework.jms.listener.AbstractMessageListenerContainer
声明,如果
"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)
stacktrace的第5行特别有趣。那里的代码基本上意味着(大多数情况下)从侦听器抛出的任何异常都将绕过在org.springframework.jms.listener.AbstractMessageListenerContainer#commitIfNecessary
中完成的ackowledget
没关系,但是“在抛出异常的情况下不重新交付”意味着什么
其他信息:
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>
# 1 楼答案
这取决于您使用的侦听器容器;使用自动确认模式时,
SimpleMessageListenerContainer
在侦听器返回后确认(即传统的JMSMessageListener
)。在调用侦听器之前DefaultMessageListenerContainer
会确认,因此需要acknowledgeMode="transacted"
来防止消息丢失这个领域的Javadoc有点误导,而且一直是improved recently
有了客户确认,你就可以自己做确认了。那个医生的意思是你是在经纪人的一时兴起。根据JMS消息javadoc:
根据我的经验,最好使用带有
SMLC
的自动确认和带有DMLC
的事务