Author |
Message
|
gupabhi |
Posted: Tue Sep 01, 2009 7:43 am Post subject: Any way to avoid 'auto-commit' on disconnect ? |
|
|
Newbie
Joined: 01 Sep 2009 Posts: 5
|
The MQ java base api has a behavioral quirk, in that it auto-commits on a call to MQQueueManager.disconnect() . I believe this a bit weird and dangerous because of the reasons I mention below. Is there anyway at all to close a connection without having it auto-commit ?
I have an asynchronous "MQServer" - bascially a thread that polls the queue and read a message and then processes it (processing can involve a put in another queue or some DB updates, etc).
I'm trying to solve a problem where if a call to backout thrown an unexpected exception (say for example an OutOfMemoryError) in my pre-backout transaction management code or the mq driver code, before the rollback command is actually sent to the queue manager. If such a situation occurs I have only one of the following options:
[Please keep in mind that loosing a message is _not_ an option in any case whatsoever. ]
1. Ignore and then reuse the same connection to read the next message from the queue and process it.
2. Close the connection
3. Have retry logic built in where if rollback fails, keep retrying until rollback is successful.
With option 1. we end up having read the first message whose processing had failed and hence we had tried to backout - which failed too. So when we read the next message and assume we process it successfully, it will eventually commit. Effectively we've lost the 1st message read on the tx. So this is not an option.
Option 2. would have been the most ideal thing to do, but MQ actully commits on a disconnect !! Again leads to effective message loss
Option 3, is most undesirable where we have a thread dedicated to retrying 'bad state' connections that have to be rolledback. This seems like way too much effort for something which could have been trivially solved if there was a way to disconnect without commit.
Have people faced a problem like this? What do people think is the best approach to solve this problem?
Thanks,
Abhi |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Sep 01, 2009 1:17 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Did you make sure to have in your open options Syncpoint specified ?
What was the error code on the rollback attempt?  _________________ MQ & Broker admin |
|
Back to top |
|
 |
gupabhi |
Posted: Tue Sep 01, 2009 2:10 pm Post subject: |
|
|
Newbie
Joined: 01 Sep 2009 Posts: 5
|
I am talking of a general situation under syncpoint. This is a fundamental problem with the way the api behaves. If the backout fails what action can you take? Ideally you'd want to close the connection so the queueManager auto backsout. But the behavior is opposite of that - disconnect() actually commits!!
To be mroe clear about this. There was no error code because the java code threw an OutOfMemoryError in the mq driver codes backout method. If something like this happens the exception is propagated all the way back to the user code. At that point, the user has only the above mentioned 3 options.
Please let me know if more clarification is needed. |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Sep 01, 2009 7:43 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Have you tried a second roll back? What happened on the second try?
It is very seldom that the UOW functions would fail, if everything was initiated properly...
Did you get any return code/ reason code?
Any FDCs created?
 _________________ MQ & Broker admin |
|
Back to top |
|
 |
gupabhi |
Posted: Wed Sep 02, 2009 7:35 am Post subject: |
|
|
Newbie
Joined: 01 Sep 2009 Posts: 5
|
2nd rollback falls under "option 3" that I suggested where a let a dedicated thread retry backouts on all such 'bad connections'. But like I said, thats not the most desirable approach.
I agree that this will seldom happen, but my use-case is for very high robustness, mission critical applications, where message loss is _not_ an option.
There is no reason code. This could simply be an OutOfMemeoryError in the mq driver code. Here is an example stacktrace
java.lang.OutOfMemoryError: Testing for OOMs at new object creation com.ibm.mq.MQInternalCommunications.buildAPIHeader(MQInternalCommunications.java:1324)
at com.ibm.mq.MQSESSIONClient.MQBACK(MQSESSIONClient.java:881)
at com.ibm.mq.MQQueueManager.backout(MQQueueManager.java:2349)
The above implies that the mq driver does not handle OOMs and lets the exception propagate to usercode. So no communication actually happened with the queueManager for the 'backout' call. Ideally I would want to just close this connection and expect the queueManager would back it out implicitly. But it does the opposite! That leads to message loss.
It seems very weird that an approach of 'commit on disconnect' was taken. It inherently can lead to message loss.
Has nobody faced this issue before? What approach have people taken and recommend?
Thanks,
Abhi |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Sep 02, 2009 4:45 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Due to the different default behavior on different platforms, I always suggest to developers to explicitly commit or rollback.
To the point of calling rollback just before disconnecting...
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
PeterPotkay |
Posted: Wed Sep 02, 2009 5:22 pm Post subject: |
|
|
 Poobah
Joined: 15 May 2001 Posts: 7722
|
If your app has an outstanding unit of work and you end cleanly (i.e. you issue disconnect), you will get an implicit commit.
If your app has an outstanding unit of work and you end abnormally (i.e. you bomb without issue disconnect), you will get an implicit rollback.
So if your processing, and your call to backout fails, and you have no other option but need to have that message rolled back.....end abnormally and MQ will rollback your message.
But don't realy on this behaviour for normal operations. As FJ stated, always code explicits rollbacks and commits wherever you need that behaviour. _________________ Peter Potkay
Keep Calm and MQ On |
|
Back to top |
|
 |
gupabhi |
Posted: Fri Sep 04, 2009 10:44 am Post subject: |
|
|
Newbie
Joined: 01 Sep 2009 Posts: 5
|
> If your app has an outstanding unit of work and you end abnormally (i.e. you bomb without issue disconnect), you will get an implicit rollback.
What do you mean by end abnormally? How do I actually 'end abnormally' ? Which api do I use? If you're talking about shutting the JVM down that is not really an option because we're talking about an enterprise application that does much more than MQ communication.
I did consider intentionally leaking the connection, but MQQueueManager has a finalizer and I believe it calls a disconnect in it. So is there really way to actually 'rollback' on disconnect?
Any thoughts on this issue appreciated.
Thanks,
Abhi |
|
Back to top |
|
 |
fjb_saper |
Posted: Fri Sep 04, 2009 12:39 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Well if you are running in a J2EE provider you should be running JMS and setting the session to rollback only when catching the error / exception...
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
gupabhi |
Posted: Fri Sep 11, 2009 7:41 am Post subject: |
|
|
Newbie
Joined: 01 Sep 2009 Posts: 5
|
> Well if you are running in a J2EE provider you should be running JMS and setting the session to rollback only when catching the error / exception...
Well, that doesn't help. I am actually using a JMS provider - my own, which uses the ibm base api. It does not matter what wrappers you use around the ibm mq base api. Bottom line is that the base api does a commit-on-disconnect and _that_ is the fundamental problem.
Any MQ gurus on this forum care to comment?
Thanks,
Abhi |
|
Back to top |
|
 |
fjb_saper |
Posted: Sat Sep 12, 2009 10:34 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
fjb_saper wrote: |
Due to the different default behavior on different platforms, I always suggest to developers to explicitly commit or rollback.
To the point of calling rollback just before disconnecting...
Enjoy  |
_________________ MQ & Broker admin |
|
Back to top |
|
 |
bruce2359 |
Posted: Sat Sep 12, 2009 11:13 am Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9471 Location: US: west coast, almost. Otherwise, enroute.
|
Quote: |
What do you mean by end abnormally? How do I actually 'end abnormally' ? |
Normal termination of an application is defined in the WMQ Application Programming Reference and WMQ Application Programming Guide. Briefly, successfully issuing the MQDISConnect (or equivalent) call is normal termination.
Examples of conditions that can cause an application to abend (abnormally terminate) include bad app coding, failing to catch mq errors (reason codes) AND failing to take appropriate action based on those errors, shutting down a qmgr other than normal quiesce, o/s failures, hardware failures. _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
|