我使用Spring的JMS(v.3.1.2)listener-container
和来自WebSphere 7的JNDI设置的JMS connectionFactory。应用程序正确处理消息(put / get),但MQ队列管理器中设置的 backout 设置似乎不起作用。
为了使消息消费失败,我使用setRollbackOnly()
的弹出交易,它确实增加了属性"退出计数"正如我所看到的那样,使用" 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队列设置为&#34; Backout Requeue Queue&#34;设置为ONEQUEUE.BOQ
,&#34; Backout Threshold&#34;到5
。
My 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();
}
}
}
Stacktrace ERROR
消息回滚5次后,监听器开始无法连接,作为输出到日志:
[org.springframework.jms.listener.DefaultMessageListenerContainer#3-14870] WARN org.springframework.jms.listener.DefaultMessageListenerContainer - JMS消息侦听器调用程序的设置失败,目的地&#39; ONEQUEUE&#39; - 试图恢复。原因:MQJMS1079:无法将消息写入死信队列。嵌套异常是com.ibm.mq.MQException:MQJE001:完成代码&#39; 2&#39;,原因&#39; 2035&#39; 。
看起来有些东西正在进行回退消息的权限,或者没有正确检索实际的回退队列,这是意料之外的,因为get / puts工作正常。仍然在寻找答案这是否是一种有效的方法。
答案 0 :(得分:2)
在回滚次数超过BackoutThreshold(BOTHRESH)中定义的数量后,JMS客户端会将有害消息放入队列的BackoutRequeueQueue(BOQNAME)中定义的回退队列中。这意味着运行JMS应用程序的用户不仅需要访问应用程序队列,还需要访问指定的退出队列。
如果无法访问或未定义回退队列,将尝试使用队列管理器的死信队列(DEADQ属性)。
当有害消息符合要重新排队到退出队列的条件时,未授予对退出队列和/或DLQ的用户ID +put
访问权限将导致MQRC_NOT_AUTHORIZED(2035)原因代码。< / p>
2035将由JMS异常报告,并且将在队列管理器错误日志中报告确切用户ID的确切队列名称上的确切缺失权限。
相关阅读