2

I've encounter the problem that if my method below fails or it's an exception I still consume the msg. I would want the functionality to do a rollback during the catch and place the msg back on the queue/topic.

public void onMessage(Message message)
{

    String messageId = null;
    Date messagePublished = null;

    try
    {
        messageId = message.getJMSMessageID();
        messagePublished = new Date(message.getJMSTimestamp());
        LOGGER.info("JMS Message id =" + messageId + " JMS Timestamp= " + messagePublished);
        process(message);
        LOGGER.info(" returning from onMessage() successfully =" + messageId + " JMS Timestamp= " + messagePublished);
    }
    catch(Throwable t)
    {
        LOGGER.error("Exception:",t);
        LOGGER.error(t.getStackTrace() + "\n Exception is unrecoverable.");
        throw new RuntimeException("Failed to handle message.",t);
    }

}
Will
  • 8,246
  • 16
  • 60
  • 92

2 Answers2

1

You can look at the different acknowledge modes that exist within JMS for this. See this article http://www.javaworld.com/javaworld/jw-02-2002/jw-0315-jms.html.

The appropriate mode for you would be Client mode. So basically, the client needs to acknowledge when they are happy they have processed the message.

You could call the acknowledge after the call to process(message), if an exception occurs in the proccess(message) method, the message will not have been dequeued as you didnt acknowledge it. We used this approach before with Oracle AQ and it works very well.

This approach means you dont have to worry about transactions for the messages on the queue (Database transactions are another story). The only thing you need to ensure is that your app can handle a call to process(message) with potential duplicate messages

Damien
  • 4,081
  • 12
  • 75
  • 126
0

you should be able to just make your onMessage method transacted.

jtahlborn
  • 52,909
  • 5
  • 76
  • 118