How to use jms.Connection.setExceptionListner to release resources and reconnect?
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.
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 sameSession
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);
}
}
}
}
精彩评论