0
votes

In our application, we receive messages from JMS Topic.

  • First I want to know if the JMS follows FIFO policy. If not, how can an application decide which is the latest message?

We consume messages ( durable subscriber and JMS session is transacted, lot of overhead ) because messages are retained at the JMS server until the transaction commits/ends. The reason we specified transaction is

  • We are using a caching ( hibernate ) technology and a transaction to use it. So, we are using two transactions, one is JMS tx and one is caching-technology tx. When we consume the message and we want all or nothing to happen until the message is committed and acknowledgement is sent to JMS. caching tx will commit first and then immediately JMS tx will commit next and message is acknowledged, otherwise, both the tx's will be rolledback and the message will be replayed. We are currently replaying the messages 3 times, and then if the exception still occurs, then we are sending the message to non-processable queue.

  • This works fine until lot of messages come at the same time to the JMS and needs to be processed by our system at the same time.

  • I would like to know what did you do when you encountered such scenario. Because, maintaining a durable subscription and a transacted session is a significant overhead over the JMS server and would drain the performance of the server.

1

1 Answers

1
votes

Message ordering for topics is not specified in the JMS spec so the official answer to that is that it is JMS implementation specific. Having said that, unless specifically overridden to do something else, I imagine that messages would be delivered in FIFO order.

For the transactions, I suggest you look into implementing two phase commit XA transactions so you do not need two separate transactions. If your cache implementation supports XA, the JMS and Cache(and DB) transactions would be one and the same.

Generally I have found that for these types of transacted messages, if you must used transacted messages, the best way to squeeze performance out is to process as many messages in one transaction as you can:

  1. Start a transaction
  2. Retrieve n messages (or all of them until there is a timeout)
  3. Process the messages
  4. Commit the transaction.
  5. Go To 1.

Another way to kill 2 birds with 1 stone is to skip the processing of the message during retrieval and simply write the retrieved messages to a transacted data store. Then have a separate thread retrieve the messages from the store (in timestamp order) and process them (separate thread - = separate transaction).