NServiceBus 事件在超时队列中结束

NServiceBus events ends in timeout queue

我正在使用 HandleMyEvent 处理事件 class

public class HandleMyEvent :  IHandleMessages<MyEvent>
{

    private readonly IBus _bus;
    private readonly IWorkorker _workerTools;


    public HandleProductInstanceEvent( IBus bus, IWorkorker worker)
    {
        _bus = bus;
        _workerTools = worker;

    }

    public void Handle(IProductInstancesUpdatedEvent message)
    {
        var worker = new myWorker(_bus, _worker);
        myWorker.DoWork(message.data);
    }
}

myWorker.DoWork 最多可以 运行 5 分钟才完成。

当发布者发送单个 "MyEvent" 时,似乎处理程序在消息在超时队列中结束之前收到 5 个事件,我猜它在放弃之前重试了 5 次。

在日志文件中我可以找到这个条目

NServiceBus.Unicast.Queuing.FailedToSendMessageException: Failed to send message to address: My.Bus.Service@MyServer ---> System.Messaging.MessageQueueException: Cannot enlist the transaction.
   at System.Messaging.MessageQueue.SendInternal(Object obj, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)
   at NServiceBus.Transports.Msmq.MsmqMessageSender.Send(TransportMessage message, Address address) in c:\work06e2123f54fce4\src\NServiceBus.Core\Transports\Msmq\MsmqMessageSender.cs:line 59

为什么会出现此错误?

您收到该错误是因为在 NServiceBus 中处理 MSMQ 消息,默认情况下,在超时为 1 分钟的事务中运行。

一旦超过事务超时,任何新操作(例如发送消息或在数据库中存储内容)都将失败并显示

Cannot enlist the transaction.

您应该 increase your transaction timeout to something more than the expected processing time or turn off transactions 在此端点上。

请注意,消息处理程序 运行 5 分钟是很长的时间。在如此长的时间内对事务资源进行事务处理并因此锁定并不是最佳选择。

一旦消息处理失败,事务回滚,将消息放回队列。然后重试您配置的许多第一级重试尝试。在您的场景中很可能是 5 个。之后,它被转移到二级重试。

.timeout 队列是超时管理器的输入队列,负责处理二级重试。如果消息没有立即从此队列中提取,则您不是 运行 该端点上的超时管理器。