views:

701

answers:

3

Hi,

I receive a message from a WebSPhere MQ queue. I try to process and if i receive some exceptions i want to rollback the message to the MQ Queue.

I have no problems in doing the same. What happens to the message? Does it go to the bottom of the queue?

If i try and pull a message from the queue would i receive the same message that i rolledback?

What is the behaviour likely to be? I want to know this behaviour typically in a high volume Queue scenario?

Appreciate any inputs.

Thanks, Manglu

+2  A: 

If you are doing queue operations within the scope of a transaction, and a rollback occurs, then after the transaction resolves the queue and message will appear just as it did before the transaction began. In other words no changes at all.

In a high volume scenario, though, it is typical to have multiple transactional readers and writers on a single queue, and they do not lock the entire queue for each de-queue or enqueue.

These readers and writers will insert items into the queue, or dequeue items from the queue transactionally, while your doomed transaction is resolving. In that case, other queue items may appear or disappear (or both).

If after rollback of the original transaction, you again dequeue from the queue, you may get the original message, but you may not. In a high-volume, high-concurrency scenario, it is possible that another reader will have pulled the message before your code can do so.

Cheeso
+1  A: 

Hi,

Rollback leaves the message on the queue and puts it up for redelivery.

However, when a (configurable) limit of redelivery attempts has been reached, the message is put aside on the "dead letter queue".

A typical example where this happens are s.c. 'poison messages': messages that can't be dealt with due to fundamental and non-transient problems (such as an invalid format, missing fields, etc).

So before you rollback (and put the message back on the queue), make sure to think about whether the error is transient (like connections to the back-end being broken) or not.

In the latter case, it is best to swallow the message and log an error or fire some other alert. Otherwise, the message will unnecessarily consume both processing power and queue infrastructure.

HTH

Guy

Guy Pardon
Marc,My understanding is that after the back out threshold is reached, the mesage is sent to the back out Queue and not to the Dead Letter Queue. It is sent to the DLQ only when the message cannot be written to the BOQ.Manglu
Manglu
A: 

To answer a couple of the specific points from this thread...

  • The message retains it's position in the queue. The GET under syncpoint locks the message but does not remove it from the queue or change it's position. Rollback releases the lock and makes the message available for redelivery.
  • The automatic requeueing of a poison message occurs with the JMS and XMS classes but not the native Java, C, C#, COBOL, etc. APIs. If you are not using JMS or XMS (which implements the JMS API for C and .Net programs) then you need to requeue the message yourself.
  • You are correct that the requeueing will be attempted on the queue named in the input queue's BOQNAME attribute after exceeding BOQTHRESH redeliveries. If that queue is not available (full, unauthorized, non-existent, etc.) then the DLQ is tried. If that fails, the message listener stops receiving messages altogether.
  • Ideally a program will handle a poison message by requeueing it and alerting on the presence of messages in the exception queue. Failing that, at least don't just consume and discard the message. Log it, along with the message headers, so someone later can reconcile what happened to it.
T.Rob