【发布时间】:2014-10-03 06:07:20
【问题描述】:
我正在使用 Spring 的 JMS (v. 3.1.2) listener-container 和来自 WebSphere 7 的 JNDI 设置的 JMS connectionFactory。应用程序正确处理消息 (put/get),但在 MQ 队列管理器中设置的 backout 设置似乎不起作用。
为了使消息消费失败,我使用带有 setRollbackOnly() 的 spring 事务,它确实增加了属性“Backout count”,因为我可以看到该数字随着“WebSphere MQ Explorer”指向远程队列而增加。
通过阅读一些 IBM 文档,它描述了 IBM MQ JMS 客户端 需要将错误消息移动到回退队列。 Spring 的listener-container 似乎并没有以启用该行为的方式使用 MQ 客户端。退出计数不断增加,好像重新排队命令不起作用。
Spring JMS 是否能够使用该功能?是否需要在 listener-container 中设置任何内容才能处理向 IBM MQ 回退队列的移动?
我的配置如下:
<tx:jta-transaction-manager/>
<jee:jndi-lookup id="connectionFactory"
jndi-name="java:comp/env/jms/myapp_queuefactory"/>
<jms:listener-container
connection-factory="connectionFactory"
transaction-manager="transactionManager">
<jms:listener destination="ONEQUEUE" ref="oneQueueListener" />
<jms:listener destination="ANOTHERQUEUE" ref="anotherQueueListener" />
<!-- many more -->
<jms:listener-container/>
IBM MQ 队列设置为“Backout Requeue Queue”设置为 ONEQUEUE.BOQ,“Backout Threshold”设置为 5。
我的Spring消息驱动POJO java代码如下:
@Transactional
public class MyQueueMDBean implements javax.jms.MessageListener {
public void onMessage(javax.jms.Message msg) {
try {
// some code that throws some exception ...
} catch (Exception e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
}
}
}
堆栈跟踪错误
消息回滚 5 次后,监听器开始连接失败,作为日志的输出:
[org.springframework.jms.listener.DefaultMessageListenerContainer#3-14870] 警告 org.springframework.jms.listener.DefaultMessageListenerContainer - 目标“ONEQUEUE”的 JMS 消息侦听器调用程序设置失败 - 试图恢复。原因:MQJMS1079:无法将消息写入死信队列。嵌套异常是 com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2035'。
似乎正在执行撤销消息的权限,或者未正确检索实际的撤销队列,这是出乎意料的,因为 get/puts 工作正常。不过,这是否是一种有效的方法仍在寻找答案。
【问题讨论】:
-
这应该只是因为队列被定义了一个回退队列和计数而发生的。您能否将您的队列定义添加到您问题中的信息中?
-
会对您已经看到 MQ 退出工作的 Spring JMS 配置指针非常感兴趣。如果您可以将其发布为答案,将不胜感激。非常感谢!
-
请将错误消息输出添加到队列管理器 AMQERR01.LOG,这将显示 2035 MQRC_NOT_AUTHORIZED 错误背后的原因。
-
我在日志中找不到任何内容,但添加更多访问权限使其工作。感谢您的帮助。
标签: jakarta-ee ibm-mq websphere-7 spring-jms