Poison messages in XMS

A poison message is a message that cannot be processed by a receiving MDB application. If a poison message is encountered, the XMS MessageConsumer object can requeue it according to two queue properties, BOQUEUE, and BOTHRESH.

In some circumstances, a message delivered to an MDB might be rolled back onto an IBM® MQ queue. This can happen, for example, if a message is delivered within a unit of work that is subsequently rolled back. A message that is rolled back is generally delivered again, but a badly formatted message might repeatedly cause an MDB to fail and therefore cannot be delivered. Such a message is called a poison message. You can configure IBM MQ so that the poison message is automatically transferred to another queue for further investigation or is discarded. For information about how to configure IBM MQ in this way, see Handling poison messages in ASF.

Sometimes, a badly formatted message arrives on a queue. In this context, badly formatted means that the receiving application cannot process the message correctly. Such a message can cause the receiving application to fail and to back out this badly formatted message. The message can then be repeatedly delivered to the input queue and repeatedly backed out by the application. These messages are known as poison messages. The XMS MessageConsumer object detects poison messages and reroutes them to an alternative destination.

The IBM MQ queue manager keeps a record of the number of times that each message has backed out. When this number reaches a configurable threshold value, the message consumer requeues the message to a named backout queue. If this requeuing fails for any reason, the message is removed from the input queue and either requeued to the dead-letter queue, or discarded.

XMS ConnectionConsumer objects handle poison messages in the same way and using the same queue properties. If multiple connection consumers are monitoring the same queue, it is possible that the poison message may be delivered to an application more times than the threshold value before the requeue occurs. This behavior is due to the way individual connection consumers monitor queues and requeue poison messages.

The threshold value and the name of the back out queue are attributes of an IBM MQ queue. The names of the attributes are BackoutThreshold and BackoutRequeueQName. The queue they apply to is as follows:
  • For point-to-point messaging, this is the underlying local queue. This is important when message consumers and connection consumers use queue aliases.
  • For publish/subscribe messaging in IBM MQ messaging provider normal mode, it is the model queue from which the Topic's managed queue is created.
  • For publish/subscribe messaging in IBM MQ messaging provider migration mode, it is the CCSUB queue defined on the TopicConnectionFactory object, or the CCDSUB queue defined on the Topic object.
To set the BackoutThreshold and BackoutRequeueQName attributes, issue the following MQSC command:

ALTER QLOCAL(your.queue.name) BOTHRESH(threshold value) 
BOQUEUE(your.backout.queue.name)
For publish/subscribe messaging, if your system creates a dynamic queue for each subscription, these attribute values are obtained from the IBM MQ classes for JMS model queue, SYSTEM.JMS.MODEL.QUEUE. To alter these settings, use:

ALTER QMODEL(SYSTEM.JMS.MODEL.QUEUE) BOTHRESH(threshold value) 
BOQUEUE(your.backout.queue.name)

If the backout threshold value is zero, poison message handling is disabled, and poison messages remain on the input queue. Otherwise, when the backout count reaches the threshold value, the message is sent to the named backout queue.

If the backout count reaches the threshold value, but the message cannot go to the backout queue, the message is sent to the dead-letter queue or, if the message is nonpersistent, it is discarded.

This situation occurs if the backout queue is not defined, or if the MessageConsumer object cannot send the message to the backout queue.

Configuring your system to perform poison message handling

The queue that XMS .NET uses when inquiring the BOTHRESH and BOQNAME attributes depends on the style of messaging being performed:
  • For point-to-point messaging, this is the underlying local queue. This is important when an XMS .NET application is consuming messages from either alias queues or cluster queues.
  • For publish/subscribe messaging, a managed queue is created to hold the messages for an application. XMS .NET queries the managed queue to determine the values for the BOTHRESH and BOQNAME attributes.
    The managed queue is created from a model queue associated with the Topic object that the application has subscribed to, and inherits the values of the BOTHRESH and BOQNAME attributes from the model queue. The model queue that is used depends on whether the receiving application has taken out a durable or non-durable subscription:
    • The model queue used for durable subscriptions is specified by the MDURMDL attribute of the Topic. The default value of this attribute is SYSTEM.DURABLE.MODEL.QUEUE.
    • For non-durable subscriptions, the model queue that is used is specified by the MNDURMDL attribute. The default value of the MNDURMDL attribute is SYSTEM.NDURABLE.MODEL.QUEUE.
When inquiring the BOTHRESH and BOQNAME attributes, XMS .NET:
  • Opens the local queue, or the target queue for an alias queue.
  • Inquires the BOTHRESH and BOQNAME attributes.
  • Closes the local queue, or the target queue for an alias queue.
The open options that are used when opening a local queue, or the target queue for an alias queue, depend on the version of IBM MQ being used:
  • For IBM MQ 9.1.0 Fix Pack 4 Long Term Support and earlier, and IBM MQ 9.1.4 Continuous Delivery and earlier: If the local queue, or the target queue for an alias queue, is a cluster queue, then XMS .NET opens the queue with the MQOO_INPUT_AS_Q_DEF, MQOO_INQUIRE and MQOO_FAIL_IF_QUIESCING options. This means that the user running the receiving application must have inquire and get access to the local instance of the cluster queue.

    XMS .NET opens all other types of local queue with the open options MQOO_INQUIRE and MQOO_FAIL_IF_QUIESCING. In order for XMS .NET to query the values of the attributes, the user running the receiving application must have inquire access on the local queue.

To move poison messages to either a backout requeue queue or the queue manager's dead letter queue, you must grant the user running the application put and passall authorities.

Handling poison messages in ASF

When you use Application Server Facilities (ASF), the ConnectionConsumer, rather than the MessageConsumer, processes poison messages. The ConnectionConsumer re-queues messages according to the BackoutThreshold and BackoutRequeueQName properties of the queue.

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().