Reliable Messaging with JMS
Reliability in message communication can be considered as one of the highly important factors for enterprise software applications. In most of the messaging models, acknowledgements and transactions are used to prevent the message losses. But before using a particular method we should be able select the most suited one according to the use-case(s). This is because increase in the reliability of the communication can often lead to low throughput.
In JMS, session are responsible for maintaining the reliability in message communication. At the creation of the session, we have to indicate the type of acknowledgement/transaction method we are using.

Transactions
JMS Session Local Transactions
Transaction is an atomic unit of work which will consist a set of produced messages and a set of consumed messages. In JMS transacted session is a series of transactions.
A JMS transaction can be completed by using either commit or rollback. After a completion of a transaction, a new transaction will begin.
Creating a transactions enabled session from a connection,
Session session = connection.createSession(true,-1);
Distributed transactions
Distributed transactions happens when transacted JMS sessions are connected with other transacted resources (databases, other JMS sessions etc…). An external transaction monitor is used to combine transactions together. Java distributed transactions are controlled by the JTA transaction demarcation API.
Message Acknowledgements
Message acknowledgements are used in both type of clients (producers and consumers) but in different ways.
DUPS_OK_ACKNOWLEDGE
This method is mentioned as lazily acknowledge. Client will send an ACK for a batch of messages (or after the time interval), but the broker doesn’t ACK the receipt of the client’s acknowledgement. If the client’s ACK is lost in the transmission, broker may transmit duplicate messages. This should be only used when the application can handle some level of duplicate messages. But it gives the benefit of reducing the workload of the JMS session on duplicate prevention (session will not be blocked for the ACKs) and will result in higher throughput.
Creating a DUPS_OK_ACKNOWLEDGE enabled session from a connection,
Session session = connection.createSession(false,Session.DUP_OK_ACKNOWLEDGE);
AUTO_ACKNOWLEDGE
AUTO_ACKNOWLEDGE guarantees the once-only delivery of messages. This is simply a “handshake” between the JMS client and the broker that happens automatically.
Creating a AUTO_ACKNOWLEDGE enabled session from a connection,
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
CLIENT_ACKNOWLEDGE
Client application must explicitly acknowledge the receipt of messages. Therefor it gives better control to the client application. But it can be bit of time consuming, because before ACKing client will have to process the message and until then the session will be blocked.
Creating a CLIENT_ACKNOWLEDGE enabled session from a connection,
Session session = connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
Call acknowledge() on the message to ACK the received message. And recover() on the Session to redeliver all the unacked messages.
References
[1]. http://docs.oracle.com/cd/E19340-01/820-6424/aerbz/index.html
[2]. https://docs.oracle.com/cd/E19340-01/820-6767/aeqdb/index.html
[3]. http://docs.oracle.com/cd/E19587-01/821-0029/aeqbk/index.html
[4]. http://download.oracle.com/otndocs/jcp/jms-2_0-fr-eval-spec/index.html
[5]. http://www.javaworld.com/article/2074123/java-web-development/transaction-and-redelivery-in-jms.html