tilex
tilex

Reputation: 1774

Correct ActiveMQ producers concurrency

ActiveMQ documentation states that Session and MessageProducer objects are not thread-safe. If I have a set of threads that can produce persistent messages then how to send them to ActiveMQ correctly being aware of whether a particular send operation is successful or not?

  1. Have a separate Session/MessageProducer for each worker thread.
  2. Create explicit set of producer threads and pass messages to them through a BlockingQueue (how to find out whether send was successful or not?).
  3. Use Future<> for the previous case to get a success state of persisting message in ActiveMQ.
  4. Simply wrap each MessageProducer.sendMessage() call in a synchronized block.

Or maybe there are any best practices for such cases. Thanks.

Upvotes: 2

Views: 1544

Answers (1)

Petter Nordlander
Petter Nordlander

Reputation: 22279

One problem with accessing a shared session between thread, like you state in 2-4 is transaction management.

If you do things in a JMS session, then you want to make sure that you know when the transaction is committed or rolled back. That happens on the session object. Multiple threads committing on the same session will cause bugs.

What's common (for instance if you look at the JmsTemplate from Spring) is that you open a new Connection/Session/MessageProducer, send a message, then close them all. This is very inefficient, but thread safe. To solve the efficiency problem, you can wrap your ConnectionFactory in a PooledConnectionFactory. That pool will lend sessions/connections to your thread when needed, and when close is invoked on the Session, it will be put back into the Pool. That way, you don't really have to care about thread safety at all. Read more on the topic here.

Of course, if you are up to some manual managing, you can go with your approach 1 and save a Session per thread. That should be the most efficient way if you have a few threads that sends a lot of messages.

Upvotes: 3

Related Questions