在事务范围内重新提交死信队列消息

时间:2017-07-07 08:05:46

标签: azureservicebus azure-servicebus-queues dead-letter

如果只有一个顶级实体能够参与交易,我如何从死信队列中读取消息并将其放回事务范围内的父队列?通常我会使用传输队列将消息从一个队列移动到另一个队列作为原子操作,但我不相信DLQ有传输队列,即使他们这样做了,我也不会有处理传输的问题队列DLQ!

我需要以安全的方式执行此重新提交,并且在重新提交过程中没有丢失消息的风险。

2 个答案:

答案 0 :(得分:0)

Azure Service Bus不允许重新提交邮件。您需要发送带有更正数据的新消息。对于在DLQ中找到的消息,您可以推迟原始消息,提交副本,如果成功,则按原始延迟时收到的序列号接收和删除原始DLQed消息。

ServiceBus360使用Deferred DLQ feature实现了类似的功能。

答案 1 :(得分:0)

虽然这是真的,但您无法重新提交DLQ消息,经过一些调查和反复试验后,我发现以下情况很有效:

  1. 使用 BrokeredMessage.Clone()
  2. 克隆DLQ消息
  3. BrokeredMessage.Properties
  4. 中删除 DeadLetterReason DeadLetterErrorDescription 条目
  5. TransactionScope 中,将克隆的邮件发送回原始队列并完成DLQ邮件。
  6. 以下是一个例子:

    using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
    {
       // Create new message
       var resubmittableMessage = originalMessage.Clone();
    
       // Remove dead letter reason and description
       resubmittableMessage.Properties.Remove("DeadLetterReason");
       resubmittableMessage.Properties.Remove("DeadLetterErrorDescription");
    
       // Resend cloned DLQ message and complete original DLQ message
       await Task.WhenAll(_messageSender.SendAsync(resubmittableMessage), originalMessage.CompleteAsync());
    
       // Complete transaction
       scope.Complete();
    }