ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ Java / JMS » Multi-threaded client connections

Post new topic  Reply to topic
 Multi-threaded client connections « View previous topic :: View next topic » 
Author Message
p.cradwick
PostPosted: Mon Mar 10, 2008 1:38 am    Post subject: Multi-threaded client connections Reply with quote

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
View user's profile Send private message Send e-mail
fjb_saper
PostPosted: Mon Mar 10, 2008 6:11 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
jefflowrey
PostPosted: Mon Mar 10, 2008 6:18 am    Post subject: Reply with quote

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
View user's profile Send private message
p.cradwick
PostPosted: Mon Mar 10, 2008 1:23 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
p.cradwick
PostPosted: Mon Mar 10, 2008 4:18 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
fjb_saper
PostPosted: Tue Mar 11, 2008 3:45 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
p.cradwick
PostPosted: Wed Mar 12, 2008 9:53 am    Post subject: Reply with quote

Acolyte

Joined: 16 May 2001
Posts: 56

Thanks for that, I'll keep it in mind.

Peter
Back to top
View user's profile Send private message Send e-mail
friedl.otto
PostPosted: Thu Mar 13, 2008 3:58 am    Post subject: Reply with quote

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
View user's profile Send private message
fjb_saper
PostPosted: Thu Mar 13, 2008 7:07 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » IBM MQ Java / JMS » Multi-threaded client connections
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.