« Async Beans Introduction | Main | Creating a WorkManager using wsadmin/jmx »

November 13, 2003

JMS session pooling in WAS 5.x

Just had a customer have a problem. The problem was this. They are sending two messages within a transaction and they had to be processed in order.

But, sometimes, the MDB on the receiving end was getting the messages out of order. The MDB side was fine, one session in the listener port with ASF disabled to process the messages serially.

So, what was up. The problem was in the way they sent the messages. They had a SLSB method called 'sendMessage' that takes a message. It looks up a QCF, gets a connection, makes a session, a queue senders, sends the message, closes everything.

Normally, JMS guarantees that all messages from a single publisher are ordered. WebSphere does connection pooling on JMS connections and JMS sessions but the way the sendMessage routine is implemented defeats this.

Connections are normally shared using transaction affinity. But, JMS connections don't know about transactions, JMS sessions do. So, the second time the app called sendMessage, WAS sometimes gets a different connection from the pool, different connection means we make a new session and hence two publishers and hence the messages lose their order sometimes as order is only guaranteed when messages originate from a single publisher.

The workarounds are:
1) Set the connection pool size to 1 for the pool, clearly, limits performance for sending so lets try something else :) but it does mean we keep getting the same connection and hence the same session/publisher and hence ordering is restored.
2) The higher levels of the code should create a single connection or session and pass it as a parameter to the sendMessage routine. Thus, the pooling works, the app gets back the same session/queue sender and we have message order.

Passing either the connection or session will work. The connection is good enough because when the app later calls createqueuesession then we look for an existing one for this transaction and use it if we find it otherwise, we make a new one and in the case of the second message, WAS will find the session that it already made for this transaction and reuse it.

Passing the session clearly works also.

So, the recommended solution is create the session further up the stack and pass it to the common send message or simply send the message in place when needed rather than use a SLSB method.

November 13, 2003 in WebSphere | Permalink


Post a comment