开发者

How to use jms.Connection.setExceptionListner to release resources and reconnect?

Assuming I have one Connection per JVM (implemented as a singleton) as a derivative of the docs which recommend having one Connection as it's a heavy object.

From the docs:

... a connection is a relatively heavyweight object. Most clients will do all their messaging with a single connection... A JMS client typically creates a connection, one or more sessions, and a number of message producers and consumers.

I'm trying to decide what to do with my Sessions, Producers and Consumers with respect to the ExceptionListener which is at the Connection level.

To the best of my understanding it is very reasonable they are no longer usable, when a JMSException is thrown, but I'm not sure what should be done once the above listener is triggered.

My Sessions are kept in a ThreadLocal<Session> which is also kept in a singleton.

I can use this to call MySessionSingleton.closeSession() in the listener but this will only close the Session which is bound to the thread in which the Exception was thrown and not all other Sessions.

In addition this does not take care of the Producers\Consumers and their reconnect.

A possible solution which I saw used and I'm reluctant to imitate is to have a Connection and a Session for every Producer\Consumer and so I can control all of the above.

Would appreciate any thoughts,

Ittai

Clarification:

My current implementation, by a former programmer, is the one I refer to above as being used and the biggest problem it poses for me is that I need several producers and consumers to use the same Session as I have a need for JTA transactions and I think (might be wrong) that I need those Producers\Consumers to share the session.

The connection was a derivative of that decision.

So basically even if I keep the relationship of one session per connection I still have the above problem when one session has multiple Producers\Consumers开发者_开发知识库.


Maybe this is a naive question as I have not much real world experience with JMS, but wouldn't it be the easiest way to call connection.close()?

The JMS API says that "There is no need to close the sessions, producers, and consumers of a closed connection."

Aditionally a global flag could be set as a signal for message handler loops etc.


I still don't see why you need to only have one Connection object :-). I'd let the application server (I assume you're running in one) take care of managing the Connection resources for you.

i.e. Use a ConnectionFactory in order to get your Connections and create your session and consumers and producers off that.

Something roughly like:

public void notify(String errorOccurrence)
{
    Connection connection = null;

    try
    {
        connection = connectionFactory.createConnection();

        Session session = connection.createSession(true, 
                          javax.jms.Session.AUTO_ACKNOWLEDGE);

        TextMessage message = session.createTextMessage(errorOccurrence);

        MessageProducer messageProducer = 
                            session.createProducer(errorOccurrenceChannel);

        messageProducer.send(message);
    }
    catch (JMSException e)
    {
        handleJmsExcption(e);
    }
    finally
    {
        if (connection != null)
        {
            try
            {
                connection.close();
            }
            catch (JMSException e)
            {
                handleJmsExcption(e);
            }
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜