gpt4 book ai didi

c# - 为什么 EF Core 在失败时重试不起作用

转载 作者:行者123 更新时间:2023-12-05 06:14:26 28 4
gpt4 key购买 nike

我已经将我的数据库上下文配置为以这种方式重试失败:

optionsBuilder.UseSqlServer(connectionString, sqlServerOptionsAction: sqlOptions => {
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 10,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null);
});

我还配置了以下拦截器:

public class DbCommandFailureInterceptor : DbCommandInterceptor
{
private int retryCount = 2;

public override async Task<InterceptionResult<int>> NonQueryExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
Throw(command);
return result;
}

public override async Task<InterceptionResult<DbDataReader>> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result, CancellationToken cancellationToken = default)
{
Throw(command);
return result;
}

private void Throw(DbCommand command)
{
if (!(command.CommandText.Contains("serverproperty")
|| command.CommandText.Contains("_MigrationHistory"))
&& retryCount > 0) {
--retryCount;
throw SqlExceptionFaker.Error10053;
}
}
}

所以基本上我期望从数据库中获取实体时命中 Throw 方法 3 次,2 次抛出异常,最后一次没有抛出异常。但实际上没有重试失败,并且在第一次异常执行后停止。我做错了什么?

我有这样的弹性交易 helper :

public class ResilientTransaction
{
private readonly DbContext _context;
private ResilientTransaction(DbContext context) =>
_context = context ?? throw new ArgumentNullException(nameof(context));

public async Task ExecuteAsync(Func<Task> action)
{
var strategy = _context.Database.CreateExecutionStrategy();
await strategy.ExecuteAsync(async () => {
using (var transaction = await _context.Database.BeginTransactionAsync()) {
await action();
await transaction.CommitAsync();
}
});
}

public static ResilientTransaction New(DbContext context) =>
new ResilientTransaction(context);
}

这是我执行它的方式:

await ResilientTransaction.New(_dbContext).ExecuteAsync(async () => {
_dbContext.Tenants.Add(new Tenant());
await _dbContext.SaveChangesAsync();
});

最佳答案

简短的回答:这是因为这种重试策略的特定实现仅针对特定异常(如 sql 超时)进行重试。

如果你想让重试对你的测试有效,你需要抛出这些特定的异常(这对于一些黑客来说可能不是一件容易的事)或者更好地编写你自己的自定义重试策略并在数据库上下文中使用它,但仅用于测试!

关于c# - 为什么 EF Core 在失败时重试不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62893900/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com