Java – ActiveMQ: dead letter queue keeps my message order

I use ActiveMQ as a proxy to deliver messages These messages are written in dabatase Sometimes, the database cannot be accessed or closed In this case, I want to roll back my message so that I can retry this message later. I want to continue reading other messages

This code works well except that the rollback message prevents me from reading other code:

private Connection getConnection() throws JMSException {
    RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
    redeliveryPolicy.setMaximumRedeliveries(3); // will retry 3 times to dequeue rollbacked messages
    redeliveryPolicy.setInitialRedeliveryDelay(5 *1000);  // will wait 5s to read that message

    ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url);
    Connection connection = connectionFactory.createConnection();
    ((ActiveMQConnection)connection).setUseAsyncSend(true);
    ((ActiveMQConnection)connection).setDispatchAsync(true);
    ((ActiveMQConnection)connection).setRedeliveryPolicy(redeliveryPolicy);
    ((ActiveMQConnection)connection).setStatsEnabled(true);
    connection.setClientID("myClientID");
    return connection;
}

I create a session this way:

session = connection.createSession(true,Session.SESSION_TRANSACTED);

Rollback is easy to ask:

session.rollback();

Suppose there are 3 messages in my queue:

1: ok
2: KO (will need to be treated again : the message I want to rollback)
3: ok
4: ok

What will my consumer do (linear sequence):

commit 1 
rollback 2
wait 5s
rollback 2
wait 5s
rollback 2
put 2 in dead letter queue (ActiveMQ.DLQ)
commit 3
commit 4

But I want to:

commit 1
rollback 2
commit 3
commit 4
wait 5s
rollback 2
wait 5s
rollback 2
wait 5s
put 2 in dead letter queue (ActiveMQ.DLQ)

So how do I configure my consumer to delay my rollback messages later?

Solution

This is actually the expected behavior because message retries are handled by the client rather than the agent Therefore, because you have 1 session binding and have set a retry policy for 3 retries before dlq, the whole retry process will block the specific thread

So, my first question is, if the database insertion fails, do you want all other databases to fail for similar reasons?

If not, the way to solve this problem is to set the retry policy of the queue to 0 retries with a specific dlq, so that the message fails immediately and enters the dlq Then another process takes it out of the dlq every 5 seconds and reprocesses it and / or puts it back to the main queue for processing

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>