Author |
Message
|
p.cradwick |
Posted: Mon Mar 10, 2008 1:38 am Post subject: Multi-threaded client connections |
|
|
Acolyte
Joined: 16 May 2001 Posts: 56
|
Hi,
I am using WMQ 6.0 on Windows and am writing a native (not JMS) Java app that uses threads to connect to
the same (one only) QM as clients, each thread having its own SRVCONN channel.
If a thread fails to connect it retries a configurable number of times.
[During development the apps are running on the same box as the server.]
For testing I created 2 threads and when they connect successfully, it all seems to work fine.
I then forced thread 1 to fail by specifying an invalid user in the MCA.
When thread 1 started first, it failed 2035 as expected, but thread 2 also failed 2035 on its first attempt,
but succeeded on its second try. Thread 1 continued to fail eventually dying.
So far so good, well almost!
I then forced thread 2 to start first, it succeeded as expected. BUT SO DID thread 1!!!
This is wrong as thread 1 should have failed with 2035. I checked that each thread was using its assigned channel.
What is happening?
It seems to me that on the second connection to the QM it returns the existing handle, and in scenario 1,
thread 2 tries again and gets a new handle.
I thought the default was that connection handles were thread safe.
My thread connection code is:
logger.logDebug(threadName + ": Channel name = "+channel);
MQEnvironment.hostname = hostname;
MQEnvironment.channel = channel;
MQEnvironment.port = port;
// MQEnvironment.properties.put("transport", "MQSeries Client");
// MQCNO_HANDLE_SHARE_NONE MQC.TRANSPORT_MQSERIES_CLIENT
mQQManager = new MQQueueManager(qManager);
You can see I am having trouble with the properties field. How do you specify this?
The doc says MQC.TRANSPORT_MQSERIES_CLIENT is a key in the hash table, so what is the second value of the pair?
Also tried to find a way of specifying MQCNO_HANDLE_SHARE_NONE even though it is meant to be the default, but no luck.
(Oh for C++, sigh!)
Any ideas about what could be wrong with the connection (method)?
Peter |
|
Back to top |
|
 |
fjb_saper |
Posted: Mon Mar 10, 2008 6:11 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
p.cradwick wrote: |
logger.logDebug(threadName + ": Channel name = "+channel); |
Peter,
Looks like you are using java and possibly an appserver form.
You should be using JMS in that case as it takes care of a lot of information for you, including pooling and such things.
Looks further that you are suffering under the misconception that MQEnvironment is an instance class. I believe it is a singleton... with all the consequences this brings to your design....
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Mar 10, 2008 6:18 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
fjb_saper wrote: |
Looks further that you are suffering under the misconception that MQEnvironment is an instance class. I believe it is a singleton... with all the consequences this brings to your design.... |
, with the further mention that you should use the hash table forms of the MQQueueManager constructor. Also be careful of specifying a qmgr name.
Thirdly, the Transport property is mentioned in the documentation clearly with an example, I believe. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
p.cradwick |
Posted: Mon Mar 10, 2008 1:23 pm Post subject: |
|
|
Acolyte
Joined: 16 May 2001 Posts: 56
|
Thanks for the replies. I changed the connection code as follows:
logger.logDebug(threadName + ": Channel name = "+channel);
Hashtable connectionProperties = new Hashtable();
/* Add the connection properties - this code causes 2059
connectionProperties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
connectionProperties.put(MQC.HOST_NAME_PROPERTY, hostname);
connectionProperties.put(MQC.CHANNEL_PROPERTY, channel);
connectionProperties.put(MQC.PORT_PROPERTY, String.valueOf(port));
mQQManager = new MQQueueManager(qManager, connectionProperties);
*/
MQEnvironment.hostname = hostname;
MQEnvironment.channel = channel;
MQEnvironment.port = port;
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
mQQManager = new MQQueueManager(qManager, connectionProperties);
logger.logInfo(threadName + ": Connected to QueueManager : " + qManager);
When I use the commented out code I get a 2059 for all threads. Is this what your warning was about re QM name Jeff? How do you fix this?
When I use the code that is uncommented it works as expected i.e. thread1 fails and thread 2 fails first attempt (well, not expected) but succeeds on the second with thread 1 starting first.
When I remove the 'blank' hashtable from the connect I get the original behaviour.
Maybe the 'blank' hashtable causes something to be cleared internally...?
Peter |
|
Back to top |
|
 |
p.cradwick |
Posted: Mon Mar 10, 2008 4:18 pm Post subject: |
|
|
Acolyte
Joined: 16 May 2001 Posts: 56
|
I spoke too soon! The above DID fail again. What I have ended up with is:
logger.logDebug(threadName + ": Channel name = "+channel);
Hashtable connectionProperties = new Hashtable();
// Add the connection properties
connectionProperties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
connectionProperties.put(MQC.HOST_NAME_PROPERTY, hostname);
connectionProperties.put(MQC.CHANNEL_PROPERTY, channel);
String portStr = String.valueOf(port);
Integer portInt = Integer.valueOf(portStr);
connectionProperties.put(MQC.PORT_PROPERTY, portInt);
mQQManager = new MQQueueManager(qManager, connectionProperties);
and so far (!) this hasn't failed but...
This is an existing app whose author is long gone from the Co. that I have to modify like Yesterday, so I am not looking to change it to use JMS classes unless absolutely necessary. I'm not well up on JMS so what could I gain by using JMS classes? Would it be worth it?
thanks
Peter |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Mar 11, 2008 3:45 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Well switching to JMS will allow you to use JNDI for getting Connection Factory and Destinations.
It will allow you to take automatic advantage of pooling the resources as well as transaction handling (use EJ Beans and MDBs), automatic backout handling functionality, etc...
On top of this the JNDI redirection layer will allow you to change qmgr without changing the program or change queues without changing the program...
If you set up your destinations as being MQ instead of JMS you suppress the RFH header and your message looks just like it did before...
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
p.cradwick |
Posted: Wed Mar 12, 2008 9:53 am Post subject: |
|
|
Acolyte
Joined: 16 May 2001 Posts: 56
|
Thanks for that, I'll keep it in mind.
Peter |
|
Back to top |
|
 |
friedl.otto |
Posted: Thu Mar 13, 2008 3:58 am Post subject: |
|
|
Centurion
Joined: 06 Jul 2007 Posts: 116
|
fjb_saper wrote: |
Well switching to JMS will allow you to use JNDI for getting Connection Factory and Destinations.
It will allow you to take automatic advantage of pooling the resources as well as transaction handling (use EJ Beans and MDBs), automatic backout handling functionality, etc...
On top of this the JNDI redirection layer will allow you to change qmgr without changing the program or change queues without changing the program...
If you set up your destinations as being MQ instead of JMS you suppress the RFH header and your message looks just like it did before...
Enjoy  |
And you trust J2EE to do all that flawlessly?  _________________ Here's an idea - don't destroy semaphores unless you're certain of what you're doing! -- Vitor |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Mar 13, 2008 7:07 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
friedl.otto wrote: |
And you trust J2EE to do all that flawlessly?  |
Well if you don't trust it why do you use a J2EE appserver??
It's just a matter of learning how to configure it right. This can be learned...
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
|