抛出异常时 Rebs 处理程序不会重试
Rebs handler doesnt retry when exception is thrown
我将 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>();
I don't use the transaction scope
很好——只有当你想在 Rebus 处理程序之外将多个总线操作组合在一起时,事务范围才存在,例如在处理网络请求时。
Rebus 处理程序中发生的所有事情都会自动组合在一起,并作为跨越传入消息处理的事务上下文的一部分提交。
编辑:问题作者的意思是 System.Trasactions.TransactionScope
,Rebus 可以使用 Rebus.TransactionScopes 包自动将其应用于消息处理程序。
我本来以为是RebusTransactionScope
,这是Rebus自己管理自己消息事务的作用域
when an exception is thrown I don't get the message re-delivered again(it is not even in the error queue)
这听起来很奇怪。您是否让异常从消息处理程序中冒出来?
我将你评论中的代码添加到你的问题中——这样阅读起来更容易:)
首先,我建议您在方法声明中使用 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
}
因为清晰多了
The second level retries are working fine but the immediate retries are not working
看来 Rebus 是直接跳到二级重试了?你能告诉我更多你是怎么想出来的吗?
我将 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>();
I don't use the transaction scope
很好——只有当你想在 Rebus 处理程序之外将多个总线操作组合在一起时,事务范围才存在,例如在处理网络请求时。
Rebus 处理程序中发生的所有事情都会自动组合在一起,并作为跨越传入消息处理的事务上下文的一部分提交。
编辑:问题作者的意思是 System.Trasactions.TransactionScope
,Rebus 可以使用 Rebus.TransactionScopes 包自动将其应用于消息处理程序。
我本来以为是RebusTransactionScope
,这是Rebus自己管理自己消息事务的作用域
when an exception is thrown I don't get the message re-delivered again(it is not even in the error queue)
这听起来很奇怪。您是否让异常从消息处理程序中冒出来?
我将你评论中的代码添加到你的问题中——这样阅读起来更容易:)
首先,我建议您在方法声明中使用 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
}
因为清晰多了
The second level retries are working fine but the immediate retries are not working
看来 Rebus 是直接跳到二级重试了?你能告诉我更多你是怎么想出来的吗?