Removing messages from the queue in ASF

When an application uses ConnectionConsumers, JMS might need to remove messages from the queue in a number of situations.

These situations are as follows:

    Badly formatted message
    A message might arrive that JMS cannot parse.

    Poison message
    A message might reach the backout threshold, but the ConnectionConsumer fails to requeue it on the backout queue.

    No interested ConnectionConsumer
    For point-to-point messaging, when the QueueConnectionFactory is set so that it does not retain unwanted messages, a message arrives that is unwanted by any of the ConnectionConsumers.

In these situations, the ConnectionConsumer attempts to remove the message from the queue. The disposition options in the report field of the message's MQMD set the exact behavior. These options are:

    MQRO_DEAD_LETTER_Q
    The message is requeued to the queue manager's dead-letter queue. This is the default.

    MQRO_DISCARD_MSG
    The message is discarded.

The ConnectionConsumer also generates a report message, and this also depends on the report field of the message's MQMD. This message is sent to the message's ReplyToQ on the ReplyToQmgr. If there is an error while the report message is being sent, the message is sent to the dead-letter queue instead. The exception report options in the report field of the message's MQMD set details of the report message. These options are:

    MQRO_EXCEPTION
    A report message is generated that contains the MQMD of the original message. It does not contain any message body data.

    MQRO_EXCEPTION_WITH_DATA
    A report message is generated that contains the MQMD, any MQ headers, and 100 bytes of body data.

    MQRO_EXCEPTION_WITH_FULL_DATA
    A report message is generated that contains all data from the original message.

    default
    No report message is generated.

When report messages are generated, the following options are honored:

  • MQRO_NEW_MSG_ID
  • MQRO_PASS_MSG_ID
  • MQRO_COPY_MSG_ID_TO_CORREL_ID
  • MQRO_PASS_CORREL_ID

If a poison message cannot be requeued, perhaps because the dead-letter queue is full or authorization is wrongly specified, what happens depends on the persistence of the message. If the message is nonpersistent, the message is discarded and no report message is generated. If the message is persistent, delivery of messages to all connection consumers listening on that destination stops. Such connection consumers must be closed and the problem resolved before they can be re-created and message delivery restarted.

It is important to define a dead-letter queue, and to check it regularly to ensure that no problems occur. Particularly, ensure that the dead-letter queue does not reach its maximum depth, and that its maximum message size is large enough for all messages.

When a message is requeued to the dead-letter queue, it is preceded by an IBM MQ dead-letter header (MQDLH). See MQDLH - Dead-letter header for details about the format of the MQDLH. We can identify messages that a ConnectionConsumer has placed on the dead-letter queue, or report messages that a ConnectionConsumer has generated, by the following fields:

  • PutApplType is MQAT_JAVA (0x1C)
  • PutApplName is " MQ JMS ConnectionConsumer "

These fields are in the MQDLH of messages on the dead-letter queue, and the MQMD of report messages. The feedback field of the MQMD, and the Reason field of the MQDLH, contain a code describing the error. For details about these codes, see Reason and feedback codes in ASF. Other fields are as described in MQDLH - Dead-letter header.

Parent topic: Plan an application with ASF