Websphere 7 + Websphere MQ 7.X + Spring Integration + JMS - Message Listener stops reading messages from Queue

StackOverflow https://stackoverflow.com/questions/22408323

Question

We are reading messages from Websphere MQ using JMS and Spring Integration.

<task:executor id="demoMessageReceiverChannelTE" pool-size="1-3" queue-capacity="5" keep-alive="1" rejection-policy="CALLER_RUNS"/>

<int:channel id="demoMessageReceiverChannel">
    <int:dispatcher task-executor="demoMessageReceiverChannelTE"/>
    <int:interceptors>
        <int:ref bean="messageReceiverInterceptor" />
    </int:interceptors>
</int:channel>

<jms:message-driven-channel-adapter
id="demoMesssageReceiverAdapter" channel="demoMessageReceiverChannel"
connection-factory="srcJmsConnectionFactory" destination="srcReceiverQueue"
error-channel="errorChannel" message-converter="demoIncomingMessageConverter"
transaction-manager="srcJmsTransactionManager" send-timeout="65000"
header-mapper="demoJmsHeaders" />

There is another system, which put message on this Queue. (Out of scope for us)

We can have 2000 messages at a time on queue to be read.

Sometimes, Message Listener stops reading messages from Queue, when I tried to troubleshoot this issue, it gives reason that there are some un-commited message on queue, which listener trying to read and won't be able to process further and hangs there itself.

As when delete that message manually from queue, it processes other message perfectly.

So how to skip such uncommitted messages, so that system can continue with next message ?

Was it helpful?

Solution

Sounds like a classic unhandled poison message problem. When the app reads a message that it cannot process, the message is backed out to the queue. It is then read back in again since it is at the top of the queue. This results in the message appearing to be under syncpoint until finally the listener gives up and stops.

Sometimes the problem is in the app and it is the app explicitly calling ROLLBACK. Sometimes though the rollback happens befor the app even sees the message. For example, if the message cannot be converted to the local code page, or other low-level error.

If this is what is happening, the answer is to define a backout queue and then alter the input queue to point at it. For example, if the input queue is called SRC.RECEIVER.QUEUE you might do something like this on the QMgr using runmqsc:

DEFINE QL(SRC.RECEIVER.QUEUE.BKOUT)
ALTER QL(SRC.RECEIVER.QUEUE) BOQNAME(SRC.RECEIVER.QUEUE.BKOUT) BOTHRESH(15)

If the problem really is a poison message, the problem message will show up in the backout queue as an uncommitted message. As soon as the app issues the next COMMIT against the source queue, the backout message will become visible in the backout queue. If no other message arrives on the source queue, the poison message will either remain uncommitted in the backout queue or possibly revert to the source queue if ROLLBACK is called by the app or QMgr.

The setup of the backout queue is simple to do and should be standard practice so I'd recommend doing it whether or not it resolves the problem. Please see Handling poison messages in WebSphere MQ classes for JMS in the Infocenter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top