NServiceBus 6中的早期消息分发存在问题。批量消息分发不起作用?

时间:2019-03-22 00:11:13

标签: nservicebus

我们将NServiceBus 6与MSMQ和RabbitMq一起使用。当我们使用带有分布式事务的MSMQ时,我们从来没有比提交分布式事务更早地调度消息。但是,当我们将其关闭并手动将其包装在事务范围内时,我们看到Nsb在处理程序执行结束之前就开始发送消息。我们的代码如下:

public Task Handle(ICommand1 message, IMessageHandlerContext context)
{
   using (var tx = _session.BeginTransaction(IsolationLevel.ReadCommitted))
   {    
       HandleMessage1(message1);

       _session.Flush();
       tx.Commit();
    }   
}

private void HandleMessage1(ICommand1 message1)
{
    // Updating database
    ...
    // Sending other Command2 to separate handler
    bus.Send<ICommand2>(x =>
    {
       ...
    });
}

从日志中,我可以看到ICommand2开始处理的时间比ICommand1处理程序设法处理的要早,因为ICommand1处理程序在提交Command1处理程序的数据更新之前,先提交数据库中的数据更改,获取“旧”数据。

由于Nsb6为我们提供了Batched message dispatch,因此我对我们不会遇到此类问题感到印象深刻。看来这不是我们的情况,我想知道为什么以及如何解决该问题。我试图在MSMQ(无分布式事务)和RabbitMq下运行它,结果是相同的。

Command2处理程序可处理Command1处理程序所做的更改,那么如何使它们顺序工作?

1 个答案:

答案 0 :(得分:2)

应使用传递到处理程序中的context完成从处理程序中发送消息。使用bus.Send()时,您可能会使用IMessageSession而不是IMessageHandlerContext,这等效于立即分发。

将代码更改为以下内容即可解决该问题:

public async Task Handle(ICommand1 message, IMessageHandlerContext context)
{
   using (var tx = _session.BeginTransaction(IsolationLevel.ReadCommitted))
   {    
       await HandleMessage1(message1, context);

       _session.Flush();
       tx.Commit();
    }   
}

private async Task  HandleMessage1(ICommand1 message1, IMessageHandlerContext context)
{
    // Updating database
    ...
    // Sending other Command2 to separate handler
    await context.Send<ICommand2>(x =>
    {
       ...
    });
}