MainframeSupports
tip week 15/2010:

Messages in MQ may be written and read without being part of any kind of commit or rollback control. You control this behavior by using the parameter MQPMO_NO_SYNCPOINT (PUT) or MQGMO_NO_SYNCPOINT (GET). If you use NO_SYNCPOINT your message will be sent straight away at PUT and disappear from the queue straight away at GET. Especially at GET you must be aware that using MQGMO_NO_SYNCPOINT implies that the message you have GET'ted is lost forever unless you PUT it back.

Using MQPMO_SYNCPOINT and MQGMO_SYNCPOINT is a different matter. At PUT the message is sent when a MQCMIT is being issued (in CICS it is an EXEC CICS SYNCPOINT) either explicit or implicit when the program/task terminates normally. At GET you access a copy of the message straight away, but the message is removed later when a commit is performed. If the program/task abends or somehow performs a rollback (by using MQBACK or EXEC CICS SYNCPOINT ROLLBACK) the PUT message is not sent (it is removed from MQ) and the GET message remains in the MQ queue. In other words the MQ message has been backed out.

Backed out messages can easily cause you a lot of trouble. If the reason for the backout is caused by the contents of a message that has been backed out then the error causing the backout reappears when you again try to GET the errorneous message which still resides on the MQ queue. This is the most famous application loop related to MQ. For those of you who have not tried it (yet) the loop typically appears when the first errorneous message arrives at a queue which triggers a CICS transaction. The CICS transaction abends, the message remains in the queue and thereby triggers the CICS transaction again and so on.

Fortunately the developers of MQ realised this problem and added a field to the message descriptor (MQMD) called backoutCount. BackoutCount is set to zero at MQPUT and incremented each time a message is backed out at GET. If you perform MQGET of messages with MQGMO_SYNCPOINT you can avoid the described problem by coding something like:

call MQGET...
if mqReturnCode = 0
  if mqmd.backout > 0
    ...Save the errorneous message...
  else
    ...normal processing of message...
else
  ...error processing...

In the example I suggest that you save the errorneous message. You can do this in another MQ queue. Such a queue is called a backout queue. You can also save the message in DB2. The general idea is to save the message so you are able to find out what is wrong with it, maybe change it or the program processing it and then put it back for processing. You may of course also ignore it completely.

There is an attribute on a MQ queue called "harden backout counter". If you set this field to "Y", MQ will increment the backout counter even when MQ is being terminated. This attribute is only meaningful for persistent queues which are able to survive an abending MQ system or normal restart of MQ. The attribute simply gives you increased liability of the contents of the backoutCount field in MQMD. It has no other impact on backoutCount.

You can read much more about backout in WebSphere MQ Application Progamming Reference. NB. The link is for a PDF download of the manual as there is no HTML version on IBMs Library Server. If you do not have access to a fast internet connection, please do not use the link. It takes a very loooooooooooooooong time to download the manual.

Previous tip in english        Sidste danske tip        Tip list