如果通过指定sessionTransacted=true或启用DefaultMessageListenerContainer上的事务管理transactionManager=jmsTransactionManager,则只要MDP中发生异常,事务就会回滚并将消息放回到队列中。然后,该消息将再次被处理,事务又一次又一次地回滚,从而创建了一个无限循环。
我想我的问题是……我在这里想念什么?如果只是意味着将一遍又一遍地处理消息,为什么还要让消息返回队列呢?
<!-- jms connection factory -->
<bean name="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:ConnectionFactory" />
</bean>
<!-- jms transaction manager -->
<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<!-- Destination for Inbound_Email_Q -->
<bean name="inboundEmailDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="queue/inbound_Email_Queue" />
</bean>
<!-- JmsTemplate for Inbound_Email_Q -->
<bean name="jmsInboundEmailTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="defaultDestination" ref="inboundEmailDestination" />
<property name="messageConverter" ref="xmlMessageConverter" />
</bean>
<!-- jms asynchronous listener -->
<bean id="emailMessageServiceMdp" class="org.site.wso.core.jms.EmailMessageServiceMdp" />
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<!-- <property name="transactionManager" ref="jmsTransactionManager" /> -->
<!-- <property name="sessionTransacted" value="true"/> -->
<property name="destination" ref="inboundEmailDestination"/>
<property name="messageListener" ref="messageListener"/>
</bean>
<!-- jms message listener adapter -->
<bean id="messageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg>
<bean class="org.site.wso.core.jms.EmailMessageServiceMdp"/>
</constructor-arg>
<property name="messageConverter" ref="xmlMessageConverter"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
这是我的MDP:
public class EmailMessageServiceMdp implements MessageDelegate {
public void handleMessage(Object object) {
EmailMessageRequestVO requestVO = (EmailMessageRequestVO) object;
try {
//Service call that throw exception
} catch (Exception e) {
throw new ApplicationException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
消息重新交付只是[已配置] JMS实现的默认行为。有待进行无休止的辩论,它的相对用途是什么,但是似乎重试是一种明智且保守的方法,而不是丢弃包含一些可能无法恢复的数据的消息。例如,在您的情况下,您似乎正在将JMS消息转换为电子邮件,然后分派到SMTP服务器。如果SMTP网关已关闭,则您可能需要保留JMS消息并在网关恢复后对其进行重新处理。
通常,我会说您处理失败处理的消息的选项是(取决于JMS实现):
如果您更喜欢#1,则只需排除异常,提交事务并向消息挥手告别。其余的,JMS配置(或目标特定的配置)应该处理那些。
此外,如果您需要更具体的信息,则可以询问消息的getJMSRedelivered()和/或特定于实现的消息标头属性,该属性指示消息已被重新传递多少次(大多数JMS实现支持,但不是标准的)并进行处理相应的消息。
| 归档时间: |
|
| 查看次数: |
2648 次 |
| 最近记录: |