1

我将 rebus 3.1.5 与 rebus.rabbitmq 3.0.0 和 rabbitmq.client 4.1.1 一起使用。我已配置为使用简单的重试策略,最多 2 次传递尝试。如果抛出异常,我想重试该消息。我不使用事务范围。但是当抛出异常时,我不会再次重新传递消息(它甚至不在错误队列中)

如果这是不可能的,并且如果我需要使用 HandleMessagesInsideTransactionScope 配置 rebus,它是否会锁定我的数据库,直到我完成处理程序工作?

非常感谢!

编辑:这是处理程序的样子:

public Task Handle(SetCreditInfoCommand command) 
{
    return Task.Run(() => {
        var loanApplication = _loanApplicationRepository.Get(command.LoanApplicationId); 
        try { 
            //something that throws an exception here
        }
        catch(Exception ex)
        {
            throw ex;
        }
    });
} 

这就是总线的配置方式:

var bus = Configure.With(adapter)
    .Transport(t => t.UseRabbitMq(connectionString, queueName))
    .Options(b => b.SimpleRetryStrategy(
            maxDeliveryAttempts: 2,
            secondLevelRetriesEnabled: true, 
            errorQueueAddress: queueName + "_error"
    ))
    .Timeouts(t => t.StoreInSqlServer(dbConnection, "RebusTimeouts", false))
    .Start();

IoC.GetContainerBuilder().RegisterInstance(bus).As<IBus>(); 
4

1 回答 1

1

我不使用事务范围

好——只有当你想在 Rebus 处理程序之外将多个总线操作组合在一起时,事务范围才存在,例如在处理 Web 请求时。

Rebus 处理程序中发生的所有事情都会自动组合在一起,并作为跨传入消息处理的事务上下文的一部分提交。

编辑:问题作者的意思是,Rebus 可以通过使用Rebus.TransactionScopesSystem.Trasactions.TransactionScope自动应用于消息处理程序。

我最初以为是RebusTransactionScope,这是 Rebus 自己管理自己的消息传递事务的范围。

当抛出异常时,我不会再次重新发送消息(它甚至不在错误队列中)

这听起来很奇怪。您是否让异常从消息处理程序中冒出?


我将您评论中的代码添加到您的问题中 - 这样更容易阅读:)

async首先,我建议您通过在方法声明中使用关键字来简化代码,如下所示:

public async Task Handle(SetCreditInfoCommand command) 
{
    // (...)
} 

接下来,我建议你现在做throw ex,因为这不是正确的重新抛出——它会破坏ex异常的堆栈跟踪。

你应该

catch(Exception ex)
{
    throw;
}

如果您绝对想捕获异常。但我真的建议你不要在你的 Rebus 处理程序中捕获异常,除非你想对它们做点什么——在这种情况下,在我看来你的处理程序会像这样更好:

public async Task Handle(SetCreditInfoCommand command) 
{
    var loanApplication = _loanApplicationRepository.Get(command.LoanApplicationId); 

    //something that throws an exception here
} 

因为它更清晰。

第二级重试工作正常,但立即重试不起作用

所以看起来 Rebus 直接跳到 2 级重试?你能告诉我更多关于你是怎么想出来的吗?

于 2017-12-13T13:30:59.110 回答