A JDBC transaction is not enough: If you have read a message, and the database operation fails, and tomcat
is shutdown, the message is lost.
If each message triggers an insert/update in a database, you could use CLIENT_ACKNOWLEDGE
mode:
final boolean transacted = false;
final int ackMode = Session.CLIENT_ACKNOWLEDGE;
final QueueSession queueSession = queueConnection.createQueueSession(
transacted, ackMode);
So you can read the message, and update the database. If the database update was successful, you can acknowledge the message using
message.acknowledge();
Without acknowledge
, the message will be redelivered: So after restarting tomcat
, your message listener should see the message again. You can use queueSession.recover()
to restart delivery programatically.
Since it is possible that tomcat
is shutdown right between a successful DB update and the acknowledge, you should make sure to handle duplicate messages correctly.
A variation is to use a transacted session:
final boolean transacted = true;
final QueueSession queueSession = queueConnection.createQueueSession(
transacted, -1);
In this mode you can acknowledge multiple messages using a single commit:
queueSession.commit();
You need this mode, if multiple messages result in a single database operation (you have to collect some messages, before you can update the database).