1

I want to concurrently consume jms messages from multiple queues. All the messages should go to the DB after long running processing and I have no right to lose them.

Question: Is it possible to save messages for future acknowledgement and call oldMessage.acknowledge() when another message is being processed?

My first guess is that this is impossible since it is deep in the jms processing unit and I have to process message and acknowledgement within an onMessage(...) method.

Second guess is to split onMessage() concurrently and allow long running processing for many messages. But this is not a good option since I have to ensure that all messages are coming ordered!
2nd question: Is there any way to ensure the incoming order while concurrency processing?

Anatoly D.
  • 317
  • 2
  • 10
  • so you have for example 2 queues, in the first one you get messages A and B and in the second you get C and D? Now there are at least two threads that read them. they also do a lot of work on them and store them in DB, right? So you want to preserve the same order when they are inserted in the DB? – Eugene Apr 16 '13 at 06:29
  • To make processing concurrent I mean to make concurrent processing of each input queue like [here](http://stackoverflow.com/questions/3088814/how-can-i-handle-multiple-messages-concurrently-from-a-jms-topic-not-queue-wit), so I think that if I have queue where are messages A and B, then I want to ensure that they come to the DB ordered – Anatoly D. Apr 16 '13 at 09:13

1 Answers1

0

1: JMS has a flag on Session that is *CLIENT_ACKNOWLEDGE* you can see it here. I never used it but seems to do what you want.

2:

2.1: You have N consumers for the same queue: You can explore the Exclusive Consumer that some implementations have support. (for AtiveMQ: here).

2.2 You have 1 consumer per queue but you want to order all messages from all queues. You can use the concept of an ordered SlackBuffer.

You can explore another possibilities like: Redirect all messages to an output queue that maintains the order of messages and you will only consume messages from that single output queue. The order of messages and the redirection are accomplished by the MQ server. It is only a valid idea if you can control the MQ server.

I hope this can help

Pedro Gandola
  • 196
  • 1
  • 11
  • about exclusive consumer: "The broker will pick a single MessageConsumer to get all the messages for a queue to ensure ordering". A single. This is already not concurrent reading from the queue – Eugene Apr 16 '13 at 06:33
  • From the [JavaDoc](http://docs.oracle.com/javaee/1.4/api/javax/jms/Message.html#acknowledge()) it is written: `A client may individually acknowledge each message as it is consumed, or it may choose to acknowledge messages as an application-defined group (which is done by calling acknowledge on the last received message of the group, thereby acknowledging all messages consumed by the session.)` Does it mean that if I call `acknowledge()` on any message I will get all consumed message acknowledged? – Anatoly D. Apr 16 '13 at 09:07
  • Anatoly, This will be applied if you are using groups of messages. That is a nice feature of some brokers. I let you [here](http://activemq.apache.org/message-groups.html) the ActiveMQ example with [this](http://activemq.apache.org/optimized-acknowledgement.html) too. – Pedro Gandola Apr 16 '13 at 10:03