This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I have the following query on JMS. I am using MDB (Message Driven Bean) to consume messages. My question is: Suppose for instance, message #1 has arrived in the queue and the MDB instantiated. Now during the processing of the onMessage method, the application goes down. Meanwhile messages #2, #3, #4 gets queued up. 1. Once the application comes up, will the message #1 be processed again or will message #2 be picked up? 2. Can we control this programatically so that any unprocessed message is processed after any failure, or 3. Is there some settings that we can do to achieve processing of unprocessed messages?
durability is what you are looking for. Are you messages durable, are they stored in some database, so that if the server crashes the message is still there and can be re-queued or redone. If it is not, then you will lose that message. Even in some cases, if they are not also saved, you will lose message 2, 3, 4
Thanks for the response. I also would like to add a few things which I got to know from my friend
His quotes : When you say " the application goes down", I would assume that there's a runtime exception which has occurred in the application (the message consumer/MDB)
I would imagine that the behaviour here is largely dependent on the transaction attributes set for the particular methods. If the bean in question (MDB ) is container managed and has a transaction context, then the EJB container does try to redeliver the message. (the number of retries is as specified in the listener port)
But in case, repeated attempts of delivering the message fail (in our case, this happens when the MDB repeatedly throws a runtime exception), then the message is placed in a dead letter queue (check if your JMS provider provides this facility. I am also told that in MQ Series we can also use Backout Requeue and Backout threshold). Then the messages have to be moved to the input queue from the dead letter queue(upon correction of the error causing the runtime exception in the MDB).
The other option which we could explore is writing the failed message into some sort of a log, from which we can programmatically recover the failed message.
The main point here is, make sure that the process of delivering and receiving the message is covered in a valid transaction context. For e.g., having the MDB's onMessage method running under "NotSupported" transaction attribute does not guarantee redelivery of failed messages!
Client: begin trans: send message() message reaches the queue the app is down? who knows? the call is asynchronous... control goes back to client client happy end trans()
Client: begin trans: send message() for whatever reason, message DOES NOT reach the queue control goes back to client WITH AN EXCEPTION client NOT happy rollback() end trans()
MDBs do not know the calling app's transactional context. You can probably make the JMS queue part of the transaction. But not the MDB, I guess. So in your case, the message is in the queue; but the app that is hosting the MDB is down. There's no way for the client which put the message in the queue to know about status of the MDB that is subscribed to the queue. After a while the application wakes up. Now, which message is the MDB going to get? Ordering is not guaranteed in JMS. Your first message will still be there. But they may get processed after all the next 6 messages are processed. Your queue does not care about the status of the MDB. The messages will sit there as long as someone takes them.
I guess I added more confusion rather than answeringthe question :-)