I think you're on the right track. There's three general patterns here:
- The message is valid and can be processed
Normal processing applies.
- The message is valid, but cannot be processed right now
Perhaps some resource you need to process the message is unavailable. In this case, set the transaction to rollbackOnly and the message will be redelivered. Hopefully your JMS implementation supports the notion of delayed redelivery so that you're not reprocessing the same message thousands of times until your MIA resource becomes available again. If not (yeah, I'm looking at you, WebSphere MQ), what I usually do is push the message into another JMS queue reserved for temporarily unprocessable messages and commit. When the MIA resource comes back on line, I procedurally read all the messages off that queue and write them back to the main [original] queue where they're processed to completion.
Suppress the exception and commit the transaction. You'll never see that message again. To keep an audit trail of invalid messages:
- Write the invalid message off to a bad queue where it can be examined later on.
- Log out the contents of the message
- Keep a JMX Counter of Invalid Messages (broken out by type, source queue, parsing error etc.)
The main point, though, is to make sure you commit the transaction if you know you will never be able to process that message.