Handling poison messages
Sometimes, a badly-formatted message arrives on a queue. Such a message might make the receiving application fail and back out the receipt of the message. In this situation, such a message might be received, then returned to the queue, repeatedly. These messages are known as poison messages. The ConnectionConsumer must be able to detect poison messages and reroute them to an alternative destination.
When an application uses ConnectionConsumers, the circumstances in which a message is backed out depend on the session that the application server provides:
- When the session is non-transacted, with AUTO_ACKNOWLEDGE or DUPS_OK_ACKNOWLEDGE, a message is backed out only after a system error, or if the application terminates unexpectedly.
- When the session is non-transacted with CLIENT_ACKNOWLEDGE, unacknowledged messages can be backed out by the application server calling Session.recover().
Typically, the client implementation of MessageListener or the application server calls Message.acknowledge(). Message.acknowledge() acknowledges all messages delivered on the session so far.
- When the session is transacted, unacknowledged messages can be backed out by the application server calling Session.rollback().
- If the application server supplies an XASession, messages are committed or backed out depending on a distributed transaction. The application server takes responsibility for completing the transaction.
The WebSphere MQ queue manager keeps a record of the number of times that each message has been backed out. When this number reaches a configurable threshold, the ConnectionConsumer requeues the message on a named requeue queue. If this requeue fails for any reason, the message is removed from the queue and either requeued to the dead-letter queue, or discarded. See Removing messages from the queue for more details.
The threshold and the name of the requeue queue are attributes of the WebSphere MQ local queue. The names of the attributes are BackoutThreshold and BackoutRequeueQName. For point-to-point messaging, this is the underlying local queue. For publish/subscribe messaging, this is the CCSUB queue defined on the TopicConnectionFactory, or the CCDSUB queue defined on the Topic. To set the BackoutThreshold and BackoutRequeueQName attributes, issue the following MQSC command:
ALTER QLOCAL(your.queue.name) BOTHRESH(threshold) BOQUEUE(your.requeue.queue.name)For publish/subscribe messaging, if your system creates a dynamic queue for each subscription, these settings are obtained from the WebSphere MQ JMS model queue. To alter these settings, we can use:
ALTER QMODEL(SYSTEM.JMS.MODEL.QUEUE) BOTHRESH(threshold) BOQUEUE(your.requeue.queue.name)If the threshold is zero, poison message handling is disabled, and poison messages remain on the input queue. Otherwise, when the backout count reaches the threshold, the message is sent to the named requeue queue. If the backout count reaches the threshold, but the message cannot go to the requeue queue, the message is sent to the dead-letter queue or discarded. This situation occurs if the requeue queue is not defined, or if the ConnectionConsumer cannot send the message to the requeue queue. See Removing messages from the queue for further details.
The embedded JMS provider in WebSphere Application Server, Version 5.0 and V5.1 handles poison messages in a way that is different to that just described for WebSphere MQ JMS. For information about how the embedded JMS provider handles poison messages, see the relevant WebSphere Application Server information center.
uj25590_