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.
Was the backout queue configured as the BOQNAME on another queue? Was the application that normally reads that queue using the JMS or XMS API?
LikeLiked by 1 person
Hi Josh,
You ask some good questions.
The queue with the uncommitted message was named in the BOQNAME on an input queue. I dont know if they used JMS or XMS. I have since found out this is in a package from a vendor, and the MQ admin people dont know what happens in side the package. I think the package is written in Java – but I dont know if they use JMS.
I also found that they sometimes get “an infinite loop” when there is a problem, and the back out count of the problem message is in the millions. But they dont know why, as they cant see inside the package.
regards
Colin
LikeLike
The KC page [Handling poison messages in IBM MQ classes for JMS](https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_8.0.0/com.ibm.mq.dev.doc/q032280_.htm) was updated in the last 6 months by Paul T and contains many more details on the back out logic. Very interesting to me was this:
—Begin Quote—
Processing poison messages for synchronous applications
If an application receives messages synchronously, by calling one of the following methods, the IBM MQ classes for JMS requeue a poison message within the unit of work that was active when the application tried to get the message:
…
This means that if the application is using either a transacted JMS context or session, then the moving of the message to the backout queue is not committed until the transaction is committed.
—End Quote—
This means that the next message on the queue will be read under the same unit of work, if it is not committed then the message on BO queue would not be either. Conversely if there is no next message to be read the BO message would sit uncommitted until a next message showed up and is committed.
LikeLike
Thank you… good reference.
LikeLike
Even after this we are not able to delete the queue with uncom, messages in it.
We trieed with distructive method(deleting the Queue file in backend and tried with delete QL(qname) purge. BUt failed. Can you advise further on this.
dspmqtrnn showing one indoubt transaction but not able to delete that using rsvmqtrn command
LikeLike