如何使用Polly进行特定异常的重试机制?

问题描述 投票:0回答:1

我正在尝试在

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);
    }
  }
}
c# concurrency cosmos
1个回答
0
投票

尝试改变这个:

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);
 }

© www.soinside.com 2019 - 2024. All rights reserved.