What we are doing is that we put, either our own ID as a JMS header, either we retrieve the ID JBossMQ has assigned to the message.
That way you can create a QueueReceiver with a selector like 'JMSMessageID = '"+theID+'"'" or "myID = '"+id"'"
calling receive will consume the message. If it returns null, no message with this id was found in the queue.
I think i'm misunderstanding here because i'm new to jms.
How can the receiver know the id?
Won't that message stay in the queue? if the receiver only get the messages that it wants?
> How can the receiver know the id?
Excellent question. Once you have call the send(YourMessage) method, YourMessage will be filled by additionnal information.
so this code will put the id into the 'id' string:
String id = msg.getJMSMessageId();
> Won't that message stay in the queue? if the receiver only get the messages that it wants?
Excuse me? If you create a receiver with a selector and you call receive on it, consumed message(s) will be put out of the queue. Now if your selector is such as it can match zero or one message, you have what you want (I gave example in my first reply).
So there is 1 receiver that gets all the messages that needs to be deleted?
I am thinking that if there are multiple receivers, then don't you need to stop the other receivers from receiving the unwanted messages?
One receiver = one message (see the selector, only one message could match. have you ever seen two messages with the same ID? If so, we have a problem). If you need to remove 10 messages, you'll have to create 10 receivers. But as far as I understand, cancelling an order should be an atomic operation right? (You don't remove 10 orders at the same time, does you?)
Regarding receivers, it depends what do you mean by cancelling an order. If the order has already been processed, it's too late, it couldn't be canceled anymore. You can translate this sentence by 'when one of my receivers processed the message'
sorry, i'm not very good at jms.
my question was if there are two types of receivers
1 to remove the message
1 to process the message
then how do you know that message will go to the correct receiver?
thanks for you help
This is not really a JMS, but an architectural issue. Your original problem was
"For example, if you use a queue to queue up orders and then the client wants to cancel the order?"
In some ways, the order should sit in the queue, waiting to be processed by some component (the receiver that processes the message). This one is triggered on some actions made on the system (The item is now available for instance).
Till the message has not been consumer (that is, till a process does not take it) it could be canceled. As soon as it is consumed, then it's not cancelable anymore. Let's say this is our architecture. If it does not fit your needs, you can adapt my solution.
Now how do you know that the message is gone to the right receiver. This is simple. If you launch the code snipper I put below and you receive a not null response, you have canceled the order. If you receive a null answer this means two things:
1/ There had never been an order with that id in your system
2/ There was an order with this ID but it has already been processed (consumed by the component that process the order.
In case 2 you can react saying it's too late to cancel. In case 1 you can simply says "order unknown" provided you have a good ID mechanism (JMSMessageID is good as far as you don't use them outside JBoss)
Jive should definitely implement an Edit feature :/
Made some typo error on my last post. The code I am talkin g about is above and not below (previous post).
Regarding the difference between case 1 and 2 (when the response is null), you can distinguish between the two if you have stored your order ID somewhere.
From what i understand,
messages from the queue are processed one by one and there can be a many receivers listening to the queue.
so if i want to remove the mesage, i must wait until the message is at the top of the queue at which time the message will be send to one of the receivers?
if message does not match the condition specified by the message selector then the receiver will not receive the message?
Maybe what I know about JMS is only relevant to MDB? so I still cannot understand how you approach works. The only easy way that I think i can remove the message is by getting the receiver to check whether the message has been flaged as deleted before processing the message.
ok, how about reordering the messages in the queue?
Man, you should read a tutorial on JMS or the free doco!
We have many problems here and your feeling of the situation is quite crazy.
> messages from the queue are processed one by one and there can be a many receivers listening to the queue.
This is almost correct. By default you can process messages at the same time as you can have X instances of the same MDB running in the container (which means that JBoss will process X JMS messages at the same time)
> so if i want to remove the mesage, i must wait until the message is at the top of the queue at which time the message will be send to one of the receivers?
NO! You didn't get the JMS selector concept as I can see ... The JMS selector allows you to filter the messages. Say you have an header 'orderID'. If you put a selector 'OrderID = 1234', the receiver will only take message that have OrderID = 1234. For that JBossMQ will browse the whole queue to see if a message is currently matching the selector. If not, it will return you 'null' (I found no message). Otherwise, one message matching the selector will be returned to you (and thus removed from the queue).
See the selector as a magic hand that can fetch a message anywhere in the queue while not preventing traditionnal receivers to do their job.
> if message does not match the condition specified by the message selector then the receiver will not receive the message?
Of course. What would be the purpose of a *selector* then?
>Maybe what I know about JMS is only relevant to MDB? so I still cannot understand how you approach works.
Am I talking English here? If you create a receiver with a selector orderId = 1234 and you do receiver.receive(); then you will delete the message with orderId = 1234 if it does exist in the queue. What's difficult understading that? Explain me.
> The only easy way that I think i can remove the message is by getting the receiver to check whether the message has been flaged as deleted before processing the message.
Explain me how you'll flag a message as deleted? If you flag the message, better remove it immediatly, no?
>how about reordering the messages in the queue?
Based on which criteria? If you want to reorder messages in a queue, you need to stop each and every receivers on the queue (Maybe you don't get that MDB are asynchronous and are fired by JBossMQ
when a message arrives on the queue). Then when the queue containing messages is idle, you will have to consume each and every message, sort them and put them back in the queue.
Once a message is in the queue, you cannot change it. it's a message.
Anyway, you should think a little bit about architecture. If you have a queue with orders and MDB connected on it. And if you want to cancel an order (that is remove a message) like this, it has basically no sense. Except when you server is highly loaded, the message will be processed almost immediatly. What's the purpose of cancelling an order if you need to do it in the next 5 seconds?
ha ha, thanks
just didn't notice there is a receive() method.
so you just have a RemoveMDB and set the selector argument and call receive().
You have a SessionBean which creates a new JMSConnection -> JMSSession -> QueueReceiver
then you associated your selector on this queueReceiver and you call receiveNoWait()
Are you gonna define an MDB for each and every message you want to delete?
Go check a tutorial, you need it!