Apache NMS с использованием ActiveMQ: как использовать режим подтверждения транзакций, но при этом каждый раз подтверждать / откатывать одно сообщение?

Я использую Apache NMS (в C#) для получения сообщений от ActiveMQ. Я хочу быть в состоянии подтвердить каждое полученное сообщение или откатить сообщение в случае ошибки.

Я решил первую часть с помощью CreateSession(AcknowledgementMode.IndividualAcknowledge), а затем для каждого полученного сообщения я использую message.Acknowledge().

Проблема в том, что в этом режиме нет опции отката. если сообщение не подтверждено - я никогда не смогу получить его снова для другого испытания. Его можно отправить только другому потребителю, но другого потребителя нет, поэтому он просто застрял в очереди.

Поэтому я попытался использовать AcknowledgementMode.Transactional, но здесь есть еще одна проблема: я могу использовать только session.Commit() или session.Rollback(), но нет способа узнать, какое конкретное сообщение я фиксирую или возвращаю обратно.

Как правильно это сделать?

2 ответа

Мое решение состояло в том, чтобы создать исключение, если (по какой-либо причине (например, исключение из события db savechanges)) я не хотел подтверждать сообщение с помощью message.Acknowledge().

Когда вы создаете исключение внутри своего расширенного метода IMessageConsumer Listener, сообщение будет снова отправлено вашему потребителю примерно 5 раз (затем оно будет перемещено в очередь DLQ по умолчанию для расследования).

Однако вы можете изменить это, используя RedeliveryPolicy в объекте соединения. Пример повторной доставки

      Policy redeliveryPolicy = new RedeliveryPolicy
{
InitialRedeliveryDelay = 5000, // every 5 secs
MaximumRedeliveries = 10,      // the message will be redelivered 10 times
UseCollisionAvoidance = true,  // use this to random calculate the 5 secs
CollisionAvoidancePercent = 50,// used along with above option
UseExponentialBackOff = false
};

Если сообщение снова не удается (после 10 раз), оно будет перемещено в очередь DLQ по умолчанию. (эта очередь будет создана автоматически) Вы можете использовать эту очередь для исследования сообщений, которые не были подтверждены другим получателем.

Оставайтесь с INDIVIDUAL_ACKNOWLEDGE, а затем попробуйте session.recover() и session.close(). Оба из них должны сигнализировать брокеру, что сообщения не будут подтверждены.

Другие вопросы по тегам