0

I need to disable message re-delivery when consumer fails to process it and calls session rollback. Goal is to keep message in queue itself without re-delivery, and my background consumers will keep on trying to process message.

In connection.getRedeliveryPolicy(), I see options to customize re-delivery delays and other settings, but I don't see any option to completely disable re-delivery. Is this even possible (preferably programmatically using connection.getRedeliveryPolicy() attributes e.g.)

Cœur
  • 37,241
  • 25
  • 195
  • 267
TechCoze
  • 491
  • 5
  • 15

2 Answers2

0

unfortunately there is no solution to deactivate the RedeliveryPolicy but you can design your code otherwise.

take a look here ActiveMQ redelivery does not work

maybe org.apache.activemq.ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE can help you but keep in mind this:

Once the broker has dispatched a prefetch limit number of messages to a consumer it will not dispatch any more messages to that consumer until the consumer has acknowledged at least 50% of the prefetched messages, e.g., prefetch/2, that it received. When the broker has received said acknowledgements it will dispatch a further prefetch/2 number of messages to the consumer to 'top-up', as it were, its prefetch buffer. Note that it's possible to specify a prefetch limit on a per consumer basis (see below).

another solution is to send messages to another queue for background consumers.

Community
  • 1
  • 1
Hassen Bennour
  • 3,885
  • 2
  • 12
  • 20
0

Well, there are a couple of tricks you can do.

The typical way is to use the built in DLQ functionality and let your rolled-back messages head to DLQ. Then you can have whatever procedure trying to handle these messages afterwards.

But if you really want to keep the rolled back messages on the queue "as-is" and not touched by the consumer more than once, it can also be achieved.

First. Set max redeliveres to one, i.e. message will be retried one time.

ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616");
RedeliveryPolicy policy = new RedeliveryPolicy();
policy.setMaximumRedeliveries(1);
cf.setRedeliveryPolicy(policy);

Then make sure to only receive non redelivered messages with a selector.

MessageConsumer cons = sess.createConsumer(sess.createQueue("FOOBAR"), "JMSRedelivered <> true");

To read the rolled back messages you would have to read with the reversed selector. Regardless, I still recommend using a separate queue for the rolled back messages, such as the built in DLQ. Much easier to deal with and less error prone.

Petter Nordlander
  • 22,053
  • 5
  • 50
  • 84