Is it possible to reliably send JMS message to the destination? By reliably I mean ensuring that if e.g. MessageProducer.send()
call fails for some reason, it will be retried automatically. I realize that transaction session may use .recover()
as last resort, but what about retrying? E.g. I have intermittent network failure in between session was established and attempted to send a message. How would recover()
help in this case?

- 53,861
- 28
- 137
- 147

- 23
- 3
-
Yes, JMS can be fully transactional. The hows and whys are complex, though, and your question is too vague to elaborate on. – skaffman Dec 13 '10 at 12:34
-
Thanks for reply! Which details should I provide to get more detailed answers? I was googling for 'jms send message reliably', and this didn't yield meaningful results. Could you give some hints on how to achieve reliable sending (from producer to destination)? Thanks! – an envy guest Dec 13 '10 at 12:41
-
Which queue manager are you using? Which kind of transaction manager abstraction (e.g. jee, spring)? Are portability and implementation-independence strong requirements? – andcoz Dec 13 '10 at 14:41
2 Answers
As far as I know, JMS do not support such behavior. You could search among specific vendor-extensions but, IMHO, it is unlikely that you find something suitable to your needs.
I see only two solutions to your problem:
Implement it. You can manage the JMS session manually, catch any exception and, if needed, use "set rollback only" function of transaction manager to invalidate the transaction.
Use a local queue to store messages and use a background service to move them to target remote queue. Note that many queue manager support this, e.g. Store and forward Queues of ActiveMQ. Obviously this way, your transaction boundary will not include remote queue.
I know that 2nd solutions is not a full answer to your problem but, many times, it is sufficient.

- 2,202
- 15
- 23
JMS doesn't specify the behavior you are looking for. In fact, JMS specifically addresses problems due to network failure by noting that you may get the same message twice and calls this a "functionally duplicate" message since from the point of view of the JMS broker, it has only been delivered once.
Since this is not part of JMS your answer lies in the different vendor implementations. For example, WebSphere MQ has a feature called "Multi-Instance Queue Manager" as of v7.0.1. A v7.0.1 client application will automatically retry the connection and even follow the QMgr from the primary to the secondary node in the event of a failure. The application blocks while this occurs and is not aware of the failover.
However, even with this behavior, your app still needs to code for the failure. For example, if using the WMQ automatic reconnect (or any provider's reconnect for that matter) you probably want to tune the length of time the app might block waiting to recover the connection so that the user doesn't experience an indefinite hang. When the call unblocks, the transaction is rolled back and any retry must occur in the code. This is appropriate since the transaction is associated with a connection that is no longer valid.

- 31,522
- 9
- 59
- 103