Handling Poison Messages
A poison message is a message in a queue that has exceeded the maximum number of delivery attempts to the receiving application. This situation can arise, for example, when an application reads a message from a queue as part of a transaction, but cannot process the message immediately because of errors. If the application aborts the transaction in which the queued message was received, the message is automatically returned to the queue. If the problem with the message is not corrected, the receiving application can get stuck in an infinite loop, starting transactions to receive the message and then aborting them, until the maximum number of delivery attempts has been exceeded and a poison message results. A poison message can obstruct the processing of other valid messages in the queue.
Handling Poison Messages
An application can move poison messages from the main queue to a retry queue. This allows the application to process valid messages from the main queue, and try to process any poison messages later. If the receiving application cannot resolve the problem with the message, it can drop the message and notify the sending application of the failure.
Poison messages can be handled by using the following MSMQ features:
Abort Count Message property
The PROPID_M_ABORT_COUNT property can be used by a receiving application to determine how many times transactional processing has been aborted on a message since it was placed in its current queue. Note that if the message is moved to or from a subqueue, its abort count is reset. This allows the application to attempt to process messages in cycles, where each cycle contains a certain number of retries that is defined by the application. For an abort count that is never reset, see the PROPID_M_MOVE_COUNT property.
Move Message property
The PROPID_M_MOVE_COUNT property can be used by a receiving application to determine how many times transactional processing has been aborted on a message during its lifetime. Unlike the PROPID_M_ABORT_COUNT property, the PROPID_M_MOVE_COUNT property is not reset when the message is moved to or from a subqueue.
When the number of retries exceeds the abort count, applications can move failing messages to a retry queue to be processed later by using the MQMoveMessage function.
If a message cannot be processed, the receiving application can choose to mark the message as rejected by calling the MQMarkMessageRejected function. This removes the message from the queue and sends a negative acknowledgement (Nack) message, with the class set to MQMSG_CLASS_NACK_RECEIVE_REJECTED, to the sending machine.