我正在尝试在
DbUpdateConcurrencyException
(link)上实施重试机制。有一些方法可以做到这一点,例如添加计数器或在 catch
块中添加逻辑以重试(此链接显示了这一点)。
在这里,我正在尝试
Polly
这样做,但没有得到想要的结果。
我在这里缺少什么?当前,逻辑转到 catch 块并抛出错误而不是重试。
代码:
public class MyService
{
private readonly ILogger<MyService> _logger;
// Using Polly for retry
private readonly RetryPolicy _policy = Policy
.Handle<DbUpdateConcurrencyException>()
.WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));
public MyService(ILogger<MyService> logger)
{
_mapper = mapper;
}
public Task<ServiceResponse<MyDto>> UpsertSpecificationsWithRetryAsync(MyDto myDto, CancellationToken cancellationToken)
{
// Expecting this to be called 3 times in case of failure, every second
return _policy.Execute(async ct => await UpsertSpecificationsAsync(myDto, cancellationToken), cancellationToken);
}
public async Task<ServiceResponse<MyDto>> UpsertSpecificationsAsync(MyDto myDto,
CancellationToken cancellationToken)
{
try
{
// To test the retry mechanism
throw new DbUpdateConcurrencyException();
}
catch (Exception exception)
{
_logger.Error(message: $"Exception while upserting options. AtdDto: {{@atdDto}} Exception: {{@exception}}",
args: new object[] { myDto, exception });
return GetExceptionServiceResponse<MyDto>(exception.GetBaseException().Message);
}
}
}
尝试改变这个:
private readonly RetryPolicy _policy = Policy
.Handle<DbUpdateConcurrencyException>()
.WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));
对此:
private readonly AsyncRetryPolicy _policy = Policy
.Handle<DbUpdateConcurrencyException>()
.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1));
还有这个:
public Task<ServiceResponse<MyDto>> UpsertSpecificationsWithRetryAsync(MyDto myDto, CancellationToken cancellationToken)
{
// Expecting this to be called 3 times in case of failure, every second
return _policy.Execute(async ct => await UpsertSpecificationsAsync(myDto, cancellationToken), cancellationToken);
}
对此:
public async Task<ServiceResponse<MyDto>> UpsertSpecificationsWithRetryAsync(MyDto myDto, CancellationToken cancellationToken)
{
// Expecting this to be called 3 times in case of failure, every second
return await _policy.ExecuteAndCaptureAsync(() => UpsertSpecificationsAsync(myDto, cancellationToken));
}
最后,如果你想在 catch 块中记录错误,你不应该用 try catch 处理错误,你应该抛出如下:
try
{
// To test the retry mechanism
throw new DbUpdateConcurrencyException();
}
catch (Exception exception)
{
_logger.Error(message: $"Exception while upserting options. AtdDto: {{@atdDto}} Exception: {{@exception}}",
args: new object[] { myDto, exception });
throw;
///return GetExceptionServiceResponse<MyDto>(exception.GetBaseException().Message);
}