Message Driven Bean(MDB) is a stateless, transaction aware J2EE component for consuming messages asynchronously. MDB’s are configured to listen any queue, and pick messages and handle them. If some exception is generated, by default it wont be handled, and thrown to container. Container decides what to do in such case, some container in case of System Exception destroy the MDB instance, GlassFish on Runtime Exception would close the connection.
When exception is generated, either the MDB can consume the exception and take necessary action, acc. to exception(this would be the case in Business Exceptions). But sometimes exception might be related to System, which we can consider as System Exception, and we need to wait for some time and retry the message handling. Inside Message Driven Bean we can configure the retry mechanism. So, when exception would be generated, there would be retry. We can consume the Application Exceptions( or Checked Exceptions, or sometimes called as Expected Exceptions), and in case of System Exceptions(unchecked Exceptions) we need a retry.
Retry can be configured using property “MaxDeliveryCnt” of ActivationConfig. We can also set the time interval between each retry, by setting property“endpointFailureRetryInterval”. Any message, which has reached the max. retry count, is considered as “Poison Message”. Poison message would be discarded by the JMS provider. But handling of poison message would depend on JMS provider. What we can do is configure a Exception Queue, where all the poison message would end. For using the Exception Queue, we need to set some properties like: we set“UseExceptionQueue” as true, And set the Queue Name in“ExceptionQueueName”, And optionally we can set the property“IncludeBodiesInExceptionQueue” as true, If we want to include the message body, when it reaches the Error Queue.
With above settings, there would be redelivery with any transaction attribute( Remember we can set either “Required” or “Not_Supported” on onMessage()).
If in my application I have many Queues - MyQ, MyQ2, MyQ3, and so on; then I will create multiple error queues - one for each queue - that is, MyErrQ, MyErrQ2, MyErrQ3, and so on.