Message-driven beans can handle messages on destinations (or endpoints) within the scope of a transaction.
There are three possible cases, based on the message-driven bean deployment descriptor setting you choose: container-managed transaction (required), container-managed transaction (not supported), and bean-managed transaction.
In the message-driven bean deployment descriptor settings, you can choose whether the message-driven bean manages its own transactions (bean-managed transaction), or whether a container manages transactions on behalf of the message-driven bean (container-managed transaction). For information about the message-driven bean deployment descriptor settings, see Message-driven bean deployment descriptor attributes. If you choose container-managed transactions, in the deployment descriptor notebook, you can select a container transaction type for each method of the bean to determine whether container transactions are required or not supported. The default container transaction type is required.
For WebSphere Application Server Version 7 and later, listener ports are stabilized. For more information, read the article on stabilized features. You should plan to migrate your WebSphere MQ message-driven bean deployment configurations from using listener ports to using activation specifications. However, you should not begin this migration until you are sure the application does not have to work on application servers earlier than WebSphere Application Server Version 7. For example, if you have an application server cluster with some members at Version 6.1 and some at Version 7, you should not migrate applications on that cluster to use activation specifications until after you migrate all the application servers in the cluster to Version 7.
In this case, the application server starts a global transaction before it reads any incoming message from the destination, and before the onMessage() method of the message-driven bean is invoked by the application server. This means that other EJBs that are invoked in turn by the message, and interactions with resources such as databases can all be scoped inside this single global transaction, within which the incoming message was obtained.
If this application flow completes successfully, the global transaction is committed. If the flow does not complete successfully, (if the transaction is marked for rollback or if a runtime exception occurs), the transaction is rolled back, and the incoming message is rolled back onto the message-driven bean destination.
In this case there is no global transaction, but the JMS provider can still deliver a message from a message-driven bean destination to the application server in a unit of work. You can consider this as a local transaction, because it does not involve other resources in its transactional scope.
The application server acknowledges message delivery on successful completion of the onMessage() dispatch of the message-driven bean (using the acknowledgement mode specified by the assembler of the message-driven bean).
However, the application server does not perform an acknowledge, if an unchecked runtime exception is thrown from the onMessage() method. So, does the message roll back onto the message-driven bean destination (or is it acknowledged and deleted)?
The answer depends on whether a syncpoint is used by the WebSphere MQ JMS provider and can vary depending on the operating platform (in particular the z/OS® operating platform can impart different behavior here).
If WebSphere MQ establishes a syncpoint around the message-driven bean message consumption in this container-managed transaction (not supported) case, the message is rolled back onto the destination after an unchecked exception.
If a syncpoint is not used, then the message is deleted from the destination after an unchecked exception.
For related information, see the technote 'MDB behavior is different on z/OS than on distributed when getting nonpersistent messages within syncpoint' at http://www.ibm.com/support/docview.wss?uid=swg21231549.
In this case, the action is similar to the container-managed transaction (not supported) case. Even though there might be a user transaction in this case, any user transaction started within the onMessage dispatch of the message-driven bean does not include consumption of the message from the message-driven bean destination within the transaction scope. To do this, use the container-managed transaction (required) scenario.
In each of the previous three cases, a message that is rolled back onto the message-driven bean destination is eventually re-dispatched. If the original rollback was due to a temporary system problem, you would expect the re-dispatch of the message-driven bean with this message to succeed on re-dispatch. If, however, the rollback was due to a specific message-related problem, the message would repeatedly be rolled back and re-dispatched. This is known as a poison message scenario.
If your messaging system uses listener ports, the application server handles this scenario, by tracking the frequency with which a specific message is dispatched, and by stopping the associated listener port after a specified number of attempted re-deliveries of that message have occurred.
If your messaging system uses activation specifications, the poison message scenario is handled in a slightly different way. Whereas listener ports track the number of times a specific message has failed and been re-delivered, activation specifications count the number of sequential message delivery failures.
As an alternative to relying on your application server to stop the listener port or activation specification if a poison message scenario occurs, you can configure WebSphere MQ to resolve the problem. In WebSphere MQ specify a backout queue (BOQUEUE), and a backout threshold value (BOTHRESH). If you do this, WebSphere MQ handles the poison message. For more information about handling poison messages, see the WebSphere MQ Using Java section of the WebSphere MQ library.