【发布时间】:2020-12-08 16:03:35
【问题描述】:
我正在使用 Polly 为暂时的 SQL 错误实施重试策略。问题是我需要将我的数据库调用包装在一个事务中(因为如果任何一个失败,我想回滚)。在我从 Polly 实现重试之前,这很容易,因为我只会捕获异常并回滚。但是,我现在使用下面的代码来实现 Polly 并重试几次。问题是,当我遇到异常并且 Polly 进行重试并且假设重试不起作用并且所有尝试都失败时,事务保持打开状态并且我收到错误消息“无法在交易”。我知道为什么会发生这种情况,因为.WaitAndRetry 将在每次尝试之前执行块中的代码。这就是我现在回滚的地方。这适用于除最后一次之外的所有尝试。
问题是,当我有事务并且需要在每次失败后回滚时,如何实现 Polly,以便即使在最后一次失败时,它仍然可以回滚?
这是我现在正在做的事情:
return Policy
.Handle<SQLiteException>()
.WaitAndRetry(retryCount: 2, sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), onRetry: (exception, retryCount, context) =>
{
connection.Rollback();
Logger.Instance.WriteLog<DataAccess>($"Retry {retryCount} of inserting employee files", LogLevel.Error, exception);
})
.Execute(() =>
{
connection.BeginTransaction();
connection.Update(batch);
connection.Insert(pkgs);
if (pkgStatus != null)
connection.Insert(pkgStatus);
if (extended != null)
connection.Insert(extended);
connection.Commit();
return true;
});
【问题讨论】: