MQ

Morag's Quirks #7: Visibility of Transactional messages

By Morag Hughson posted Tue April 21, 2020 05:50 AM

  
Morag's
Quirks
This is part of an occasional series of small blog posts where I (Morag) will write about some of the quirks in IBM MQ, in the hope of invoking the response, "Well, I didn't know that!" Read other posts in this series.

A behaviour of IBM MQ that often catches out people is the way that messages which are part of an in-progress transaction are accounted for.

Current Depth

The most common of these is the current depth, which displays a depth that accounts for messages that are part of a transaction. What does that mean? Well, it means that if a message has been MQPUT to a queue, but not yet committed, that it shows up in the count of current depth. It also means that if a message has been MQGET from a queue, but not yet committed, that its removal shows up in the count of current depth. Let's show a couple of little examples to make that clear.

  • We start with an empty, unused queue.
    DISPLAY QSTATUS(Q1) CURDEPTH UNCOM
    AMQ8450I: Display queue status details.
       QUEUE(Q1)                               TYPE(QUEUE)
       CURDEPTH(0)                             UNCOM(NO)
  • Now we put a message, using MQPMO_SYNCPOINT, and we can see that even though the message is unavailable to be consumed by any other application, it counts towards the current depth.
    DISPLAY QSTATUS(Q1) CURDEPTH UNCOM
    AMQ8450I: Display queue status details.
       QUEUE(Q1)                               TYPE(QUEUE)
       CURDEPTH(1)                             UNCOM(1)
  • Now we commit the message.
    DISPLAY QSTATUS(Q1) CURDEPTH UNCOM
    AMQ8450I: Display queue status details.
       QUEUE(Q1)                               TYPE(QUEUE)
       CURDEPTH(1)                             UNCOM(NO)
  • Now we get the message, using MQGMO_SYNCPOINT, and we can see that message no longer counts towards the current depth, even though the transaction it is in has not yet been committed
    DISPLAY QSTATUS(Q1) CURDEPTH UNCOM
    AMQ8450I: Display queue status details.
       QUEUE(Q1)                               TYPE(QUEUE)
       CURDEPTH(0)                             UNCOM(1)
  • Now we commit the message.
    DISPLAY QSTATUS(Q1) CURDEPTH UNCOM
    AMQ8450I: Display queue status details.
       QUEUE(Q1)                               TYPE(QUEUE)
       CURDEPTH(0)                             UNCOM(NO)

As shown in this example, the UNCOM attribute on DISPLAY QSTATUS is very useful at showing you that there are a number of messages currently in a transaction that should be taken into account when viewing this status information. Read an earlier blog post for more about UNCOM.

Message Age

Another attribute that may reflect messages that are part of a transaction is the MSGAGE attribute on DISPLAY QSTATUS. This attribute shows how old the oldest message on the queue is, in seconds. The oldest message on the queue, may be a message that has been consumed from the queue in a transaction that is not yet committed, so it doesn't show up in the current depth, but it still shows up as the oldest message on the queue.

In the above graph, you could be forgiven for being somewhat confused by what you are seeing! How can the age of the oldest message be increasing if there are no messages on the queue?

Let's look at what actually happened in this graph.

  • Before 14:49:10, the queue was empty and had a getting application waiting to process messages in syncpoint.
  • At 14:49:10 a message was put to the queue outside of syncpoint. It was immediately retrieved by the getting application, which then took 5 seconds to process it before committing the transaction.
  • The current depth is at zero for these 5 seconds as the message is part of the getters transaction, but the message age is seen increasing until that message is committed.
  • At 14:49:15 the message is committed, and so message age returns to zero.
  • At 14:49:16 another message was put to the queue and we see the same again.

So it is clear that message age will reflect the age of the oldest message on the queue, even if that message is part of a transaction and does not show up in the current depth. So, always remember to look at the UNCOM attribute to fully understand the status you are looking at.

This post was prompted by someone asking a similar question because they ended up with a graph that they couldn't explain. Adding UNCOM to the graph might also have helped.

Remember, whatever you are doing, if the current depth doesn't gel with something else you are seeing, always remember to check UNCOM!


Morag Hughson is an MQ expert. She spent 18 years in the MQ Devt organisation before taking on her current job writing MQ Technical education courses with MQGem. She also blogs for MQGem. You can connect with her here on IMWUC or on Twitter and LinkedIn.

#mquirks
#IBMMQ
#ChampionsCorner
2 comments
33 views

Permalink

Comments

Fri May 01, 2020 05:35 AM

Hi @Peter Potkay

Yes indeed, the MAXDEPTH isn't absolute, you can indeed "trick" it in this way. Now that MQ V9.1.5 has MAXFSIZE (Max File Size), that is a better way of being more certain about the amount of space a queue file might take up.

Cheers,
Morag

Thu April 30, 2020 03:55 PM

Getting messages under syncpoint (first set), then putting more messages outside of syncpoint (second set), then rolling back the original set is a sneaky way of seeing Current Depth > Max Q Depth!

Example:
Max Q Depth 100
Put 100 messages. Commit. Q Depth = 100
Get 100 messages under syncpoint, don't commit. Q Depth = 0
Put 50 more messages. Commit. Q Depth = 50.
Rollback your gets. Q Depth = 150 but Max Q Depth =  100