If you are talking to any JMS transport provider over the network, use transacted sessions and make sure the app detects and gracefully deals with dupe messages. Why? Have a look at the JMS 1.1 specification in section 4.4.13 Duplicate Production of Messages which states:
If a failure occurs between the time a client commits its work on a Session and the commit method returns, the client cannot determine if the transaction was committed or rolled back. The same ambiguity exists when a failure occurs between the non-transactional send of a PERSISTENT message and the return from the sending method.
It is up to a JMS application to deal with this ambiguity. In some cases, this may cause a client to produce functionally duplicate messages.
A message that is redelivered due to session recovery is not considered a duplicate message.
Consider an application that issues a COMMIT
over the network. If the app receives an error indicating the connection has been broken, how does it know whether that happened before or after the API call reached the transport provider? If the app was sending a message, the only safe thing to do is to assume the COMMIT
failed and resend the message. The thing receiving the message will see it again.
Similarly, an app receiving messages that gets an error on the COMMIT
will see that message again if in fact it was rolled back. However, the app cannot assume that it was rolled back and discard the message it has just received because that may result in lost messages.
So WMQ or any other JMS transport provider must not deliver a dupe but because of an ambiguity introduced by the network, the application might receive a dupe. This is best case assuming a transacted session and the app gracefully handles dupes. Worst case is that outside of a transacted session, the ambiguity might result in the app dropping messages.