The most reliable way to consume a message is to do so within a transaction, either from a queue or from a durable subscription to a topic. For details, see Creating Temporary Destinations, Creating Durable Subscriptions, and Using JMS API Local Transactions.
For other applications, a lower level of reliability can reduce overhead and improve performance. If your application does not use transactions, it can use one of these acknowledgement modes: auto, duplicates okay, and client.
If your application uses transactions, it can choose from these transaction options: transacted session, MDB with container-managed transaction demarcation (CMTD), and MDB with bean-managed transaction demarcation (BMTD).
Read the full blog post.