Configure Container-Managed Transactions
32.1.1. Using Container-Managed Transactions When an MDB is using Container-Managed Transactions (CMT), the delivery of the message is done within the scope of a JTA transaction. The commit or rollback of this transaction is controlled by the container itself. If the transaction is rolled back then the message delivery semantics will kick in (by default, it will try to redeliver the message up to 10 times before sending to a DLQ). Using annotations this would be configured as follows: @MessageDriven(name = "MDB_CMP_TxRequiredExample", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/testQueue") }) @TransactionManagement(value= TransactionManagementType.CONTAINER) @TransactionAttribute(value= TransactionAttributeType.REQUIRED) @ResourceAdapter("hornetq-ra.rar") public class MDB_CMP_TxRequiredExample implements MessageListener { public void onMessage(Message message)... } The TransactionManagement annotation tells the container to manage the transaction. The TransactionAttribute annotation tells the container that a JTA transaction is required for this MDB. Note that the only other valid value for this is TransactionAttributeType.NOT_SUPPORTED which tells the container that this MDB does not support JTA transactions and one should not be created. It is also possible to inform the container that it must rollback the transaction by calling setRollbackOnly on the MessageDrivenContext. The code for this would look something like: @Resource MessageDrivenContextContext ctx; public void onMessage(Message message) { try { //something here fails } catch (Exception e) { ctx.setRollbackOnly(); } } If you do not want the overhead of an XA transaction being created every time but you would still like the message delivered within a transaction (i.e. you are only using a JMS resource) then you can configure the MDB to use a local transaction. This would be configured as such: @MessageDriven(name = "MDB_CMP_TxLocalExample", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/testQueue"), @ActivationConfigProperty(propertyName = "useLocalTx", propertyValue = "true") }) @TransactionManagement(value = TransactionManagementType.CONTAINER) @TransactionAttribute(value = TransactionAttributeType.NOT_SUPPORTED) @ResourceAdapter("hornetq-ra.rar") public class MDB_CMP_TxLocalExample implements MessageListener { public void onMessage(Message message)... }