Reputation: 101
I am creating a JMS listener application which listens on a queue. I am using TIBCO JMS implementation and facing an issue that intermittently more than one of my listener threads pick up a same message and that results in duplicate processing.
Here is how I am creating the connection: . .. ...
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.PROVIDER_URL, url);
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactoryClass);
env.put(Context.SECURITY_PRINCIPAL, userName);
String decryptedPass = null;
//Decryption logic
try {
// Look up queue connection factory from naming context.
if (log.isEnabledFor(Level.DEBUG)) {
log.debug("Attempting to lookup queue connection factory at '" +
this.url + "' as user '" + userName + "'.");
}
Context ctx = new InitialContext(env);
QueueConnectionFactory factory =
(QueueConnectionFactory) ctx.lookup(connectionFactoryName);
// Create JMS connection using the factory we just looked up.
if (log.isEnabledFor(Level.DEBUG)) {
log.debug("Creating queue connection as user '" + userName + "'.");
}
connection = factory.createQueueConnection(userName, decryptedPass);
...
..
.
Then here I am creating the listener threads with the same connection created above
//This is called in a loop.
// Create a JMS session that is non-transacted, but in client
// acknowledge mode. This will allow us to control when
// messages are acknowledged.
QueueSession session =
getQueueConnection().createQueueSession(
false, Tibjms.EXPLICIT_CLIENT_ACKNOWLEDGE);
// Create a receiver for the queue we are interested in. Then
// set the message listener defined on the outer class. Messages
// will be delivered on a dispatcher thread created by the
// JMS provider.
Queue queue = session.createQueue(getQueueName());
session.createReceiver(queue).setMessageListener(getListener());
...
..
.
Now here let us assume, 5 listener threads are created and they listen as receivers on a queue. I am seeing a behavior that sometime more than one listener thread/receiver picks up the same message and I end up with duplicate processing? How can I handle it through JMS configuration? Is it even possible? Or I would have to resort to some programmatic solution? Any advise would be much appreciated. Thanks.
Upvotes: 2
Views: 4112
Reputation: 15273
When a message is delivered to an application, that message is hidden (or not available to other consumers) from the queue till the application acknowledges it. The message is removed from the queue only after application acknowledges that message. The message will reappear in the queue if the consumer goes away without acknowledging. So when a message is hidden, then that message won't be available to other consumers.
The point I am trying to make here is: a message should not have been given to more than one consumer concurrently. You may want to recheck your listener code.
Upvotes: 2
Reputation: 509
try to change Tibjms.EXPLICIT_CLIENT_ACKNOWLEDGE to javax.jms.Session.AUTO_ACKNOWLEDGE
or make sure you Listener acknowledges about receiveing message.
Upvotes: 0