How to check whether the message has been delivered or not?

I'm trying to send a message to a queue and the message will expire in 20 seconds if no one picks it up. Is there any listener I can set so I can know it when message is not delivered and expired?
[204 byte] By [dan2005a] at [2007-11-26 14:25:05]
# 1

Do you want to do this as a one off test to see that everything is working correctly or in your application for real?

If 1. use a visual queue browser like hermes

If 2. If delivery is that important the client should send a non-expiring acknowledgement to a reply queue from within the same session. That way you'll always know (after a period of time) whether the message was consumed or not.

A lame alternative would be to not expire the original message, but write a new MessageListener with a message selector that only read messages over 20 seconds old.

SteveNaivea at 2007-7-8 2:17:57 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2

Thanks for your help. I'm in 2nd situation that I want this feature in my application.

Let me explain the scenario a bit more. The server has many clients connected. Each client listens to its own queue. When server send a message to client A, the client A is supposed to handle message A. If in some occasion that client A die, the server will wait for 20 seconds and send it to client B. In this case, client B will handle the message, and client A wouldn't wanna see the message once it's back because the message has already been handled by client B.

I was thinking if jms has a mechanism for this type of reliable transmission. Now it seems I have to write my own framework that manages those sessions. Are there any easier ways do it?

dan2005a at 2007-7-8 2:17:57 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3

Why not have both Client A and Client B processing messages from the same queue? The messages will only be processed once, but if Client A fails, Client B will continue processing messages.

In your scenario you stated that you want Client B to take over if Client A fails, but have you consisidered what will happen if Client A reads a message and fails half way through processing it. Can you afford to lose the message?

Can Client A process the message in a distributed transaction so it is rolled back onto the queue in the event of failure?

SteveNaivea at 2007-7-8 2:17:57 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 4

Thanks Steve. I'm thinking of doing it your way that both client A and B listen to the same queue. As you mentioned distributed transaction, I'm not that familiar with jms transaction. One scenario I can think is, say client A needs to perform 5 tasks when received the message. If client A dies when doing 3rd task, how does the server know if client A died and roll back the message to the queue? Does it do this through some timeout machanism?

dan2005a at 2007-7-8 2:17:57 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 5

> One scenario I can think is, say client A needs to perform 5 tasks when received the message. If client A dies when doing 3rd task, how does the server know if client A died and roll back the message to the queue? Does it do this through some timeout machanism?

The safest solution to this problem is to ensure you use a distributed transaction to read and process the message, however this is only possible if you're doing something like inserting the message into a database and the database driver also supports distributed transactions. If you're doing file processing / calling a web service etc. you will just have to accept that in specific error scenarious you wont' be able to guarantee the state of your system.

However this is not always a problem. Ask yourself...

1. What are the implications of processing a message twice?

2. What are the implications of never processing a message?

3. What are the implications of half processing a message?

If the answer to 1 is "none" then simply keep the JMS transaction open until the message has been processed. Any time you get a system error (e.g. cannot connect to web service), rollback the JMS transaction. The message will be redelivered and reprocessed. It's important to differenciate between system and business errors however. You should not rollback the transaction on business errors (e.g. invalid message conent) because you'll end up with an infinite loop.

If the answer to 2 is "not the end of the world", then you could just log the error and discard the message

If the answer to 3 is "a catastrophe" then you have no option but to use distributed transactions as mentioned above.

There are various tweaks to the above options, such as incorporating retry counts and backout queues, but only worry about these once you know the answer to questions 1, 2 & 3.

SteveNaivea at 2007-7-8 2:17:57 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 6

I am in trouble for getting the acknoledgmet from the receiver as My product is used for the transferring data between 2 diffrent applications

at any point .....

I have been using the untransacted session with AUTO_ACKNOWLEDGE I am new to JMS and dosnt know where to see for the acknowledgment..

Milind.Chaudharia at 2007-7-8 2:17:57 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...