.NET Core 2.1 MVC中MySQL 5.7瞬态故障处理方案咨询
嘿,我来帮你搞定这个问题!你碰到的情况很典型——EnableRetryOnFailure确实是EF Core专门给SQL Server做的扩展方法,MySQL的驱动并没有内置这个功能。不过别慌,我们有两种可靠的方式来实现重试、延迟等策略,还能正确使用你自定义的MyStrategy类。
一、正确使用自定义的ExecutionStrategy
你已经创建了MyStrategy类,接下来只需要把它和你的DbContext绑定起来,并且确保类本身的实现符合EF Core的要求。
1. 完善自定义策略类
首先,你的MyStrategy需要正确实现构造函数,并且重写ShouldRetryOn方法来判断哪些异常值得重试(比如MySQL的连接超时、死锁等)。推荐用依赖注入友好的构造函数写法:
using Microsoft.EntityFrameworkCore.Storage; using MySqlConnector; // 注意引用MySQL的异常类,根据你用的驱动调整 public class MyStrategy : ExecutionStrategy { // 依赖注入式构造函数,EF会自动传入所需依赖 public MyStrategy(ExecutionStrategyDependencies dependencies) : base(dependencies, maxRetryCount: 10, maxRetryDelay: TimeSpan.FromSeconds(30)) { } // 重写该方法,定义哪些异常需要触发重试 protected override bool ShouldRetryOn(Exception exception) { // 针对MySQL 5.7的常见可重试异常做判断 if (exception is MySqlException mySqlEx) { // 根据MySQL错误码筛选,以下是常见的可重试场景: return mySqlEx.Number switch { 1205 => true, // 锁等待超时,事务回滚 2002 => true, // 无法连接到MySQL服务器 2013 => true, // 查询过程中丢失连接 2055 => true, // 连接服务器超时 // 可以根据你的需求添加更多错误码 _ => false }; } // 也可以包含其他通用的可重试异常,比如网络超时 return exception is TimeoutException; } }
2. 在DbContext配置中绑定自定义策略
接下来,在注册DbContext的时候,通过UseExecutionStrategy方法指定你的自定义策略。这里要注意不同MySQL驱动(比如Pomelo或官方MySql.EntityFrameworkCore)的配置细节略有不同,以下是Pomelo的示例:
services.AddDbContext<MyContext>(options => { options.UseMySql( mysqlConnection, new MySqlServerVersion(new Version(5, 7)), // 指定MySQL 5.7版本 sqlOptions => { // 绑定自定义执行策略 sqlOptions.UseExecutionStrategy<MyStrategy>(); }); });
如果是使用官方的MySql.EntityFrameworkCore,代码类似,只是版本参数的写法可能稍有差异,但UseExecutionStrategy的用法是通用的。
二、替代方案:用Polly集成更灵活的重试策略(可选)
如果你需要更复杂的重试逻辑(比如指数退避、熔断等),可以结合Polly库来实现。不过这种方式需要你手动包装EF的操作,示例如下:
// 先定义Polly重试策略 var retryPolicy = Policy .Handle<MySqlException>(ex => new[] {1205, 2002, 2013}.Contains(ex.Number)) .Or<TimeoutException>() .WaitAndRetry(10, retryAttempt => TimeSpan.FromSeconds(Math.Min(30, Math.Pow(2, retryAttempt)))); // 使用策略包装EF操作 await retryPolicy.ExecuteAsync(async () => { using var context = serviceProvider.GetRequiredService<MyContext>(); // 执行你的EF操作,比如SaveChanges或查询 await context.SaveChangesAsync(); });
不过要注意,这种方式和EF Core内置的ExecutionStrategy的区别在于:内置策略会处理EF的事务一致性问题(比如重试时会重新创建上下文),而Polly需要你自己确保操作的幂等性。
内容的提问来源于stack exchange,提问作者ABC DEF

