The above question was raised by an MQ administrator who is not an MQ programmer, the second question was – is this a bug in MQ.
To application programmers the answers may appear be obvious, but has some subtleties.
- If you use MQPUT1 to put a message within syncpoint, the queue is open for a very short time.
- If you use MQOPEN, MQPUT to put the message within sycnpoint ,…. do some work MQCLOSE
You should then do a commit to make it happen.
If the application does not do a commit, but returns, and the thread ends, the queue manager will do a commit or backout ( depending on a platform) as part of end of task clean up so you should not get an uncommitted unit of work.
So why is there an uncommitted message after the application “ends”.
The transaction was running on a web server, and the connections were being reused, and so in concept the threads run until the web server is shut down.
If the application is running as a Message Driven Bean, there is logic which does
- The message listener waits for a message and gets it.
- The message is passed to the onMessage method of the application
- The application puts a message and returns.
- Being an MDB there is an MQ Commit which commits both the get and the update.
In this case the message will be committed, and you do not get an uncommitted message.
Hmmm , the plot thickens…
It looks like there was a java application which was not an MDB. The queue name had “BACKOUT.QUEUE” as part of the name.
I expect there was an MQGET and there was a problem with the message, or there was a problem doing an MQPUT, and, in either case, the message was written to the backout queue. I am guessing that this is in error handling code which very rarely gets used, it was unlikely to have been tested properly.
The application needs to put in an explicit commit statement.
What commands are there to help me?
On my test system I paused my application after the close, and before the commit.
DIS QSTATUS(COLINMON) gave me
dis qstatus(COLINMON) ALL AMQ8450I: Display queue status details. QUEUE(COLINMON) TYPE(QUEUE) CURDEPTH(1048) IPPROCS(0) OPPROCS(0) UNCOM(1)
So no instances with the queue open, but one uncommitted message.
Use the dspmqtrn command
dspmqtrn -i -m QMA There are no matching prepared or heuristically completed transactions. dspmqtrn -e -m QMA There are no matching prepared or heuristically completed transactions.
These commands display the indoubt status. You only get indoubt when there are two resource managers involved for example MQ and DB2.
dspmqtrn -q -a -m QMA> aa
-a means display all transactions
-q mesage display the first 100 objects used by each transactions
In the aa file ( I searched for COLINMON) was
TranNum(0,24589) TRANSTATE(ACTIVE) UOWLOGDA( ) UOWLOGTI( ) UOWSTDA(2019-12-10) UOWSTTI(08.48.37) UOWLOG( ) EXTURID(XA_FORMATID XA_GTRID XA_BQUAL) CONN(5F51EF5D045CDE24) PID(9380) TID(8) APPLTAG(jpcf/myprog) APPLDESC(IBM MQ Channel) CHANNEL(QMACLIENT) CONNAME(127.0.0.1) QMURID(0.24589) USERID(colinpaice) OBJECT(COLINMON )
The QMURID(0.24589) and TranNum(0,24589) refer to the same value, the position in the log.
Using the CONN information
dis CONN(5F51EF5D045CDE24) all AMQ8276I: Display Connection details. CONN(5F51EF5D045CDE24) EXTCONN(414D5143514D41202020202020202020) TYPE(CONN) PID(9380) TID(8) APPLDESC(IBM MQ Channel) APPLTAG(jpcf/myprog) APPLTYPE(USER) ASTATE(NONE) CHANNEL(QMACLIENT) CLIENTID( ) CONNAME(127.0.0.1) CONNOPTS(MQCNO_SHARED_BINDING,MQCNO_GENERATE_CONN_TAG) USERID(colinpaice) UOWLOG( ) UOWSTDA(2019-12-10) UOWSTTI(08.48.37) UOWLOGDA( ) UOWLOGTI( ) URTYPE(QMGR) EXTURID(XA_FORMATID XA_GTRID XA_BQUAL) QMURID(0.24589) UOWSTATE(ACTIVE) CONNTAG(MQCT5F51EF5D045CDE24QMA_2018-08-16_13.32.14jpcf/myprog)
you could also have issued
DIS CONN(*) all WHERE(QMURID,EQ,0.24589)
When the web server was used, the APPLTAG type info was “WebLogic” instead of jpcf/myprog. All I could tell was which web server had been running the transaction.
UOWSTDA(2019-12-10) UOWSTTI(08.48.37) tells the start date and time of the unit of work.
UOWLOGDA( ) UOWLOGTI( ) tells the start date and time the connected first wrote to the log. As there is no date and time, there was no write to the log, so in this case the message was non persistent.
What a lot of information from a seemingly obvious question! Thanks to Gwydion for help with some of the trickier bits of this.