Author |
Message
|
richardellery |
Posted: Tue Apr 17, 2007 7:52 am Post subject: Uncommitted ghost messages with java XA in bindings mode |
|
|
Newbie
Joined: 16 Apr 2007 Posts: 7
|
Hello,
I am using the code below to test the java XA transactional behaviour of MQ for Windows 5.3 CSD12.
If a java process dies (or is killed) before a transaction is committed, it appears that the transaction is not rolled back on the queue manager. This is evidenced (in the case of my test code below) by the queue depth incrementing, but the message put to the queue is a ghost message i.e. it is not visible on the queue. I am using bindings mode, and have ensured this by running the code with the TCP listener process stopped.
dspmqtrn shows that the transaction is not in doubt, which is what we expect, since prepare() has not been called. The only way to close the transaction and make the queue depth go back to 0 is to restart the queue manager.
It appears that the queue manager is not detecting that the client has disappeared, despite the fact it is running in bindings mode.
Does anyone know how to ensure that the queue manager detects the client is missing and automatically rolls back the transaction as soon as the client is killed?
This is my code:
MQXAQueueManager xaQMrg = new MQXAQueueManager("qmSBL4323");
MQXAResource xaRes = xaQMrg.getXAResource();
Xid xid = new MyXid(123456, "1234".getBytes(), (""+id).getBytes());
qMgr = xaQMrg.getMQQueueManager();
// start new transaction
xaRes.start(xid, XAResource.TMNOFLAGS);
MQMessage hello_world = new MQMessage();
hello_world.writeUTF("Hello World!");
int openOptions = MQC.MQOO_OUTPUT ;
MQQueue myQueue = qMgr.accessQueue("qlTestIn", openOptions,
null, null, null);
com.ibm.mq.MQPutMessageOptions pmo = new com.ibm.mq.MQPutMessageOptions();
pmo.options = pmo.options | MQC.MQPMO_SYNCPOINT;
myQueue.put(hello_world,pmo);
// end transaction
xaRes.end(xid, XAResource.TMSUCCESS);
Thread.sleep(50000); // This is where I kill the java process. N.B. It has not been prepared or committed at this point! _________________ Richard Ellery |
|
Back to top |
|
 |
markt |
Posted: Tue Apr 17, 2007 8:07 am Post subject: |
|
|
 Knight
Joined: 14 May 2002 Posts: 508
|
This is behaving correctly.
After xa_end, the transaction is not "attached" to any connection. It is considered in idle state. It should NOT be rolled back; it is NOT considered indoubt. The transaction could, in theory, be continued by a completely different connection.
Your TM should know the state of the transaction, and decide what to do with it. The XA specification does not define or require any timeouts on idle transactions.
If the connection disappears BEFORE the xa_end, then the transaction would be rolled back. |
|
Back to top |
|
 |
BenR |
Posted: Tue Apr 17, 2007 8:15 am Post subject: |
|
|
Acolyte
Joined: 31 Jan 2006 Posts: 60 Location: Hursley, UK
|
I still think that this bit
Quote: |
MQXAQueueManager xaQMrg = new MQXAQueueManager("qmSBL4323");
MQXAResource xaRes = xaQMrg.getXAResource();
Xid xid = new MyXid(123456, "1234".getBytes(), (""+id).getBytes());
|
Is a really bad idea. Why are you doing it? |
|
Back to top |
|
 |
richardellery |
Posted: Tue Apr 17, 2007 8:40 am Post subject: |
|
|
Newbie
Joined: 16 Apr 2007 Posts: 7
|
Hello,
Thanks for the response so far on this..
Firstly, the reason I believed that the transaction should roll back in the case of an idle client is this article on the IBM site:
"The message will be rolled back automatically in bindings/XA and client/non-XA mode without the use of the ClientIdle parameter. "
http://www-1.ibm.com/support/docview.wss?rs=171&context=SSFKSJ&q1=clientidle&uid=swg21197630&loc=en_US&cs=utf-8&lang=en
Secondly, the reason I am doing this:
MQXAQueueManager xaQMrg = new MQXAQueueManager("qmSBL4323");
MQXAResource xaRes = xaQMrg.getXAResource();
Xid xid = new MyXid(123456, "1234".getBytes(), (""+id).getBytes());
is that I wanted to build a very simple client without involving a transaction manager. I am in the process of testing a transaction manager with MQ and wanted to understand the behaviour of MQ series independent of the transaction manager. I know that it is not a good idea for production code  _________________ Richard Ellery |
|
Back to top |
|
 |
jefflowrey |
Posted: Tue Apr 17, 2007 8:52 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
You can't do XA without a transaction manager. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
richardellery |
Posted: Tue Apr 17, 2007 9:04 am Post subject: |
|
|
Newbie
Joined: 16 Apr 2007 Posts: 7
|
You're correct you do always need a transaction manager, but in this case my client is also acting as the transaction manager. _________________ Richard Ellery |
|
Back to top |
|
 |
BenR |
Posted: Tue Apr 17, 2007 10:54 pm Post subject: |
|
|
Acolyte
Joined: 31 Jan 2006 Posts: 60 Location: Hursley, UK
|
I would be very cautious about any conclusions you get from your testing - you will get no guarantees that MQXAQueueManager methods will necessarily (a) work or (b) function in the same way as published, apparently similar counterparts in the MQQueueManager class. While the MQXAQueueManager methods may be 'public' in the Java sense and are visible to a suitable code editor they're not part of a published API.
The base Java API is not intended for use with an external transaction manager under any circumstances; the only time an external transaction manager is supported is with the JMS API, and, even then, only when running in a supported application server environment - in effect WebSphere Application Server, certain versions of WebLogic, or, using the JCA resource adapter, in a suitable J2EE1.4-certified server. |
|
Back to top |
|
 |
richardellery |
Posted: Wed Apr 18, 2007 1:02 am Post subject: |
|
|
Newbie
Joined: 16 Apr 2007 Posts: 7
|
Thanks very much for your reply, Ben.
As I understand it, the JCA adapter is only available from WMQ 6.0.2.
Are you therefore stating that the only J2EE application servers that are supported for use with WMQ 5.3 in XA mode are Weblogic and WAS?
My app server vendor (not BEA or IBM) has a WebSphere MQ adapter (for 5.3) that they claim supports XA. I also know that it uses MQXAQueueManager under the covers. Is your view that this is not supported by IBM? _________________ Richard Ellery |
|
Back to top |
|
 |
BenR |
Posted: Wed Apr 18, 2007 1:40 am Post subject: |
|
|
Acolyte
Joined: 31 Jan 2006 Posts: 60 Location: Hursley, UK
|
Hi Richard
JCA was shipped with WMQ 6.0.2.1, but will talk to a 5.3 queue manager in client mode. Of course, you would need the transactional client to do XA in this case.
The list of supported software for WMQ 5.3 can be found here
http://www-1.ibm.com/support/docview.wss?rs=171&uid=swg27006464
although you will need to consult the platform-specific versions for detailed information. This lists the supported transaction monitors. However, it needs to be read with these caveats
- base Java provides no public API for running under the control of an external transaction manager
- JMS only supports XA within the application server environment
So the net effect is that - unless you use the JCA resource adapter - the only supported servers are WAS and certain levels of Weblogic. The JCA support statement is here
http://www-1.ibm.com/support/docview.wss?uid=swg27009524 |
|
Back to top |
|
 |
richardellery |
Posted: Wed Apr 18, 2007 2:02 am Post subject: |
|
|
Newbie
Joined: 16 Apr 2007 Posts: 7
|
Ben, you are a star! This information is exactly what I was looking for. Thanks again. _________________ Richard Ellery |
|
Back to top |
|
 |
rchen |
Posted: Fri May 18, 2007 10:13 am Post subject: sample program to deal with this kind of hgost message |
|
|
Newbie
Joined: 18 May 2007 Posts: 1
|
I am currently designing an jbi componet to interface with mq, I just wrote a simple program to rollback the ghost message, I got the clue from you guys. I am not in binding mode, just tcp/ip mode, you get MQXAresource, then call recover on MQXAresource, you get back a list of Xids in doubt, then I rollback all the transactions, I guess you may choice to commit those transaction, this is a configurable param in Sun's glassfish app server, i.e. rollback v.s. commit for in doubt transaction.
My simple program acts us TM, but in App Server real TM case, it would do
a recovery scan for you automatically upon crash and recover.
xaqm = new MQXAQueueManager(qmgrname, mqProps);
xaRes = xaqm.getXAResource();
Xid[] recoverbaleXids = xaRes.recover(XAResource.TMSTARTRSCAN);
int recvblelen = recoverbaleXids.length;
if ( recoverbaleXids.length != 0)
{
for (int i = 0; i<recvblelen; i++ )
{
Xid theRecoveryXid = recoverbaleXids[i];
System.out.println("Recoveble xid"+theRecoveryXid.toString());
xaRes.rollback(theRecoveryXid);
}
} else
System.out.println("no recoveryable xids"); |
|
Back to top |
|
 |
|