Author |
Message
|
meetgaurav |
Posted: Sat Nov 15, 2008 2:19 am Post subject: |
|
|
Voyager
Joined: 08 Sep 2008 Posts: 94
|
Thanks atheek,
Actually I have an existing remote system and IBM DB2 Database. The middle ware is written in VC++. And this will set the out going message id as the incoming mesage id and the remote system will identify the message using the message id. Now we are replacing the VC++ to MDB.
So the existing remote system is identifying the client message using the message id and not Correlation Id.
Also I checked that in C program is possible to set the message id for out going messages.
Now the client is expecting the same thing from MDB also. Because client wont change the existing remote system..
Please advice |
|
Back to top |
|
 |
atheek |
Posted: Sat Nov 15, 2008 3:00 am Post subject: |
|
|
 Partisan
Joined: 01 Jun 2006 Posts: 327 Location: Sydney
|
How about using mq java api ( instead of jms) within the onMessage method of your mdb? You can set message Id for the outgoing message using java api as you can do from C |
|
Back to top |
|
 |
meetgaurav |
Posted: Sat Nov 15, 2008 3:18 am Post subject: |
|
|
Voyager
Joined: 08 Sep 2008 Posts: 94
|
Yes this is Good Idea Atheek. Whether any side effects of changing the logic now.(From JMS to Java API)
I mean on XA transaction. Curently XA is perfectly working. |
|
Back to top |
|
 |
meetgaurav |
Posted: Sat Nov 15, 2008 3:26 am Post subject: |
|
|
Voyager
Joined: 08 Sep 2008 Posts: 94
|
Now in My deploymemt descriptors am using the Queue Connection factory and Queue look up is not needed rite...???
It will create more changes on the frame work rite?? |
|
Back to top |
|
 |
atheek |
Posted: Sat Nov 15, 2008 3:31 am Post subject: |
|
|
 Partisan
Joined: 01 Jun 2006 Posts: 327 Location: Sydney
|
meetgaurav wrote: |
Yes this is Good Idea Atheek. Whether any side effects of changing the logic now.(From JMS to Java API)
I mean on XA transaction. Curently XA is perfectly working. |
You need to test and see. Do the MQPut with syncpoint option.
It worst case if this doesn't work you may end up with duplicate messages, but you can guarantee there wont be any message loss. |
|
Back to top |
|
 |
atheek |
Posted: Sat Nov 15, 2008 3:32 am Post subject: |
|
|
 Partisan
Joined: 01 Jun 2006 Posts: 327 Location: Sydney
|
meetgaurav wrote: |
Now in My deploymemt descriptors am using the Queue Connection factory and Queue look up is not needed rite...??? |
You dont need the Queue and Connecion Factory objects any more. Use a property file to specify the queue and queue manager names |
|
Back to top |
|
 |
meetgaurav |
Posted: Sat Nov 15, 2008 6:07 am Post subject: |
|
|
Voyager
Joined: 08 Sep 2008 Posts: 94
|
Hi atheek,
Could you please check whether the below code makes sound(for MQOUT SYNC). Also for CMT (XA) I need to close the queue and disconnect the Qmgr or not needed. Please advice.
try {
MQQueueManager qMgr = new MQQueueManager(qManager);
int openOptions = MQC.MQOO_OUTPUT ;
MQQueue SDLQ = qMgr.accessQueue("SYSTEM.DEFAULT.LOCAL.QUEUE",
openOptions, null, null, null);
MQMessage hello_world = new MQMessage();
hello_world.writeUTF("Hello World!");
MQPutMessageOptions pmo = new MQPutMessageOptions();
String messageId = "MessageId goes here.....";
hello_world.messageId = messageId.getBytes();
String correlationId = "CorrelationId goes here.";
hello_world.correlationId = correlationId.getBytes();
SDLQ.put(hello_world,pmo);
System.out.println("The message is put.....");
SDLQ.close();
qMgr.disconnect();
}
catch (MQException ex) {
System.out.println("An MQ error occurred : Completion code " +
ex.completionCode +
" Reason code " + ex.reasonCode);
} catch (java.io.IOException ex) {
System.out.println("An error occurred writing to message buffer: " +
ex);
}
} |
|
Back to top |
|
 |
atheek |
Posted: Sat Nov 15, 2008 6:42 am Post subject: |
|
|
 Partisan
Joined: 01 Jun 2006 Posts: 327 Location: Sydney
|
To syncpoint the put specify MQC.MQPMO_SYNCPOINT in PutMessageOptions:
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options=MQC.MQPMO_SYNCPOINT
Close the queue and disconnect from queue manager in the try block itself. Dont explicitly call MQQueueManager.commit() to commit the syncpoints.
The MQPut will be committed by the XA transaction if it is in visibility of the xa transaction.
Else, the syncpoint will be committed when MQQueueManager.disconnect() is called.
In case of exception call MessageDrivenContext.setRollBackOnly()[to rollback the message to MDB source queue]. Test if this rollbacks the message mqput to output queue as well. If it doesn't work call MQQueueManager.backout also in the catch block for the exceptions.
I haven't tried this..so not sure whether it will work..but give a try. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sat Nov 15, 2008 8:50 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20763 Location: LI,NY
|
OK guys. You're in a J2EE environment and using base MQ....
You really want to kill performance. At least use a connection pool...
You could also optimize the life of the MDB:
- on creation: acquire the connection
- on activation acquire the connection
- on passivation release the connection/ disconnect
- on destroy release the connection/ disconnect
- on finalize release the connection/disconnect
However in my opinion you should still not rely on any msgId.
The right thing to do would probably be:
get the message from MDB (JMS). Retrieve msgID.
Check correlation ID. If equal to MQC.MCI_NONE, set correlationId = retrieved msgID. Make sure destination is of type targetClient=1 and send to destination.
Happy testing [/list] _________________ MQ & Broker admin |
|
Back to top |
|
 |
meetgaurav |
Posted: Sat Nov 15, 2008 9:32 am Post subject: |
|
|
Voyager
Joined: 08 Sep 2008 Posts: 94
|
Do you think Java API in J2EE env will be less performance..
JMS in the J2EE env
JAVA API in the J2EE env
which is high performance???
If suppose I use Java API. No need to configure Q and Q MGR related stuffs in Deployment descriptors. Then how this will be visible to XA(CMT). I guess the XA related(CMT) stuffs will not support JAVA API..
Please advice |
|
Back to top |
|
 |
atheek |
Posted: Sat Nov 15, 2008 2:28 pm Post subject: |
|
|
 Partisan
Joined: 01 Jun 2006 Posts: 327 Location: Sydney
|
Acquiring a new connection to the queue manager for each invocation of the onMessage method is costly performance wise. A new connection is requested when you call the MQQueueManager = new MQQueueManager().
You can create a connection during ejb create and use it within the onMessage method. After completion, just don't release the connection
To ensure that your mdb is not leaking connections call disconnecT() during ejb_destroy.
meetgaurav wrote: |
I guess the XA related(CMT) stuffs will not support JAVA API.. |
You need to test and see this. Dont call MQQueueManager.commit() explicitly and test if the put is committed when the XA commits.If it does so it means the java api syncpoint is visible under XA transaction. If not call MQQueueManager.commit() explicitly. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sat Nov 15, 2008 4:04 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20763 Location: LI,NY
|
I don't believe you can do XA in java base where the qmgr is not the transaction controller. If you can, it will require some really fancy coding...
This is why I suggested you go the full JMS route. You have to treat your forwarding MDB like a server process in the request reply process. This is why you need to move the msgid to correlid if the correlid is not already set.
At the same time as your target client is not JMS just set the right value on the destination. Alternatively look into the uri form of the destination.
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
atheek |
Posted: Sat Nov 15, 2008 8:37 pm Post subject: |
|
|
 Partisan
Joined: 01 Jun 2006 Posts: 327 Location: Sydney
|
meetgaurav wrote: |
So the existing remote system is identifying the client message using the message id and not Correlation Id.
Also I checked that in C program is possible to set the message id for out going messages.
Now the client is expecting the same thing from MDB also. Because client wont change the existing remote system..
Please advice |
I think meetgaurav doesn't have a choice to use correlation Id. Now he's struck with the only option of using java api.
If MQ Put is not visible under XA, he can still use single phase commit and get atleast once Quality of Service. Should be fine if duplicates are not a issue for his business case.
If I remember correctly he mentioned using transacted sessions for the MQ output from the mdb in one of his previous posts. The same behaviour can be achieved using java api and syncpoints within the mdb code. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sat Nov 15, 2008 8:51 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20763 Location: LI,NY
|
meetgaurav wrote: |
So the existing remote system is identifying the client message using the message id and not Correlation Id.
Also I checked that in C program is possible to set the message id for out going messages.
Now the client is expecting the same thing from MDB also. Because client wont change the existing remote system..
Please advice |
While I understand your plight, this is still no excuse to go against best practice, and in this case remind the management that JMS gives you no control over messageId and only allows you to set correlationId.
It would certainly be a minor change to the receiving program, and would put the installation at a much better standard of being able to handle correctly whatever else is being thrown at it.
Instead of thinking about pitfalls and stop gaps to keep your remote system unchanged, you should be demonstrating to the management the reasons for fixing it up right and fixing it at the right place. (Just because a programing language / API allows you to do something does not mean it is best practice or that it should be done.)
On top of this in MQ Base there are flags (on the request message) that govern the behavior of a service's way to look at returning the message. (correlid as msgid etc...) From what you wrote so far it doesn't look like this has been implemented either...
In JMS the rule is quite simple: If the correlationId is initial (MQC.MCI_NONE) pass the messageId to the correlationId for the response. If the correlationId is set on the request message it is a pass through for the response message....
And finally if you really need to jump through hoops here is an elegant way:
Have JMS set the messageid to correlation Id and write the message to a local queue. You can have this queue triggered to pick up the message in java base or C etc... and have this little utility set the messageid to the correlation id and clear the correlation id and forward the message on to it's final destination... so full JMS in the J2EE environment and no JMS at all in the utility.... Have fun
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
meetgaurav |
Posted: Mon Nov 17, 2008 10:42 pm Post subject: |
|
|
Voyager
Joined: 08 Sep 2008 Posts: 94
|
Quote: |
You can create a connection during ejb create and use it within the onMessage method. After completion, just don't release the connection
|
If I didn't disconnect the Qmgr in the on message method. Then the remote machine is not able to access the message rite ??
Once I disconnect the Qmgr. the message will be visible to remote machine rite?? |
|
Back to top |
|
 |
|