users@glassfish.java.net

Re: Produce Message From Message Driven Bean - createQueueConnection

From: Cheng Fang <Cheng.Fang_at_Sun.COM>
Date: Tue, 16 Oct 2007 21:02:07 -0400

Pls see my comments inline...

glassfish_at_javadesktop.org wrote:
> We are using Message Driven Bean to
> - get the message from a Queue
> - process it
> - and Produce the processed messages to a Queue
>
> This question is regarding producing message from a Message Driven Bean
>
> In the Sun Java System App Server 9.1 performance tunning guide's "Tuning Message-Driven Beans" section it is mentioned
>
> http://docs.sun.com/app/docs/doc/819-3681/abebw?a=view
>
> [u][b]Caution[/b][/u]:
> Previous to version 8.1, it was possible to reuse a connection with a servlet or EJB component.That is, the servlet could call getConnection() in its init() method and then continually call getSession() for each servlet invocation. If you use JMS within a global transaction, that no longer works: [i]applications can only call getSession() once for each connection.[/i] After than, the connection must be closed (which doesn’t actually close the connection; it merely returns it to the pool). This is a general feature of portable J2EE 1.4 applications; the Sun Java System
> Application Server enforces that restriction where previous (J2EE 1.3-based) application servers did not.
>
> and also in the next paragraph "[u][b]Limit Use of JMS Connections[/b][/u]"
> When designing an application that uses JMS connections make sure you use a methodology that sparingly uses connections, by either pooling them or using the same connection for multiple sessions.
>
> [u][b]The above two seem contradictory[/b][/u].
>
Yeah, but in essence they are both talking about efficiently sharing
connections among multiple components.
> In our scenario what would be the best suited option to produce a message from MDB:
>
> 1. create a static connection object from the QueueConnectionFactory in the ejbCreate() method
> put a synchronised lock on it and use this in all the instances of the Bean to create QueueSession
>
> instance level declarations
>
> @Resource(mappedName = "jms/ConnectionFactory")
> private QueueConnectionFactory queueConnectionFactory;
> private static QueueConnection queueConnection = null;
> private static Object lockCon = new Object();
> private static Object lockSession = new Object();
>
> in ejbCreate()
> synchronized(lockCon){
> if(queueConnection == null){
> queueConnection = queueConnectionFactory.createQueueConnection();
> queueConnection.start();
> }
> }
>
>
> while producing the message on to the queue
>
> synchronized(lockSession){
> qSession = queueConnection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
> }
>
> [b]Advantage[/b]:
> - we are just using one connection per application.
> - recommended approach in the "Limit Use of JMS Connections" section
>
> [b]Disadvantage[/b]:
> - connection is not pooled and contradicts the caution statement.
> - In this approach we see few of the messages getting orphaned on the "mq.sys.dmq" queue
> - where and when do we close the connection as it is shared by all the instances.
>
>
Besides the poor sharing, EJBs are not allowed to handle thread
operations, e.g., via synchronized
> 2. create a new connection(non static) object from the QueueConnectionFactory in the ejbCreate() and close the connection in the ejbRemove()
>
> [u][b]Advantage[/b][/u]:
> - we do not get any orphaned messages on the "mq.sys.dmq" queue.
> - appears to perform better than #1 approach
> [u][b]Disadvantage[/b][/u]:
> - the bean hangs on to the connection till its instance is created.So not a very efficient use of Connection Pooling
>
>
Since MDB is pooled, all instances including idle ones have their
dedicated connections, which is a waste. Instance removal is up to the
container and some instances may never be removed. Besides, the
connection in those idle instances may time out and become unusable.
> 3. create a connection object in the onMessage() get a session out of it produce message and close the connection in the finally.
>
> [b]Advantage[/b]:
> - onMessage always gets a refreshed connection from the QueueConnectionFactory.
>
> [b]Disadvantage[/b]:
> - contradicts the statement in the "Limit Use of JMS Connections" block.
>
>
This is what I understand the preferred approach described in the above
docs.
> Please suggest what should be the best approach. we need lot of processing through put in this system.
> [Message sent by forum member 'singhrvijay2007' (singhrvijay2007)]
>
> http://forums.java.net/jive/thread.jspa?messageID=240497
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: users-help_at_glassfish.dev.java.net
>
>