You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Standard 2.1下使用MySql.Data时如何识别MySqlException中的瞬态错误?

我正好遇到过类似的问题,在使用MySql.Data和.NET Standard 2.1开发时,确实没有内置的IsTransient属性来快速判断临时异常。不过我们可以通过自定义扩展方法结合MySQL的瞬态错误代码来解决这个问题,下面是具体的实现方案和相关细节:

解决方法:自定义瞬态异常判断逻辑

我们可以给MySqlException写一个扩展方法,通过匹配错误代码来判断是否为临时异常。这种方式灵活且完全可控,适配.NET Standard 2.1的环境。

扩展方法实现

using MySql.Data.MySqlClient;
using System.Collections.Generic;

public static class MySqlExceptionExtensions
{
    // 预定义MySQL常见的瞬态错误代码集合
    private static readonly HashSet<int> TransientErrorCodes = new HashSet<int>
    {
        1040,  // 连接数过多(Too many connections)
        1042,  // 无法解析主机地址(Can't get hostname for your address)
        2002,  // 无法通过Socket连接本地MySQL服务
        2003,  // 无法连接到指定主机的MySQL服务
        2006,  // MySQL服务器已断开连接(MySQL server has gone away)
        2013,  // 查询过程中丢失与服务器的连接
        2026,  // SSL连接错误
        1205,  // 锁等待超时(Lock wait timeout exceeded)
        1213,  // 检测到死锁(Deadlock found when trying to get lock)
        1203,  // 用户连接数超过限制
        1153,  // 数据包大小超过max_allowed_packet限制(临时调整配置或重试可能解决)
        1154,  // 读取通信数据包时出错
        1156,  // 写入通信数据包时出错
    };

    /// <summary>
    /// 判断MySQL异常是否为临时可重试的异常
    /// </summary>
    public static bool IsTransient(this MySqlException ex)
    {
        return TransientErrorCodes.Contains(ex.Number);
    }
}

使用示例

在捕获异常时直接调用扩展方法即可:

try
{
    // 执行你的数据库操作逻辑
    using var conn = new MySqlConnection("你的连接字符串");
    conn.Open();
    // ...
}
catch (MySqlException ex)
{
    if (ex.IsTransient())
    {
        // 处理临时异常:比如执行重试逻辑、记录告警等
        Console.WriteLine($"检测到临时MySQL异常(错误码:{ex.Number}),准备重试...");
    }
    else
    {
        // 非临时异常,直接抛出或进行针对性处理
        throw;
    }
}
常见MySQL瞬态错误代码说明

上面集合中的错误码对应以下典型的临时场景:

  • 1040/1203: 服务器连接数耗尽,等待其他连接释放后重试即可
  • 2002/2003/2013: 网络波动、服务器临时重启或未启动,恢复后可正常连接
  • 2006: 长时间无操作导致连接被服务器回收,重新建立连接即可
  • 1205/1213: 事务锁冲突或死锁,重试事务大概率可以成功
  • 1153/1154/1156: 网络数据包传输异常,重试操作可能恢复
额外注意事项
  • 不同MySQL版本的错误码可能略有差异,建议结合你使用的MySQL版本官方文档核对补充
  • 实现重试逻辑时,建议使用指数退避策略(比如第一次等2秒,第二次等4秒,以此类推),避免短时间内频繁重试给服务器带来额外压力
  • 如果使用Polly等重试库,可以直接结合这个扩展方法配置重试规则,示例:
    var retryPolicy = Policy
        .Handle<MySqlException>(ex => ex.IsTransient())
        .WaitAndRetry(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
    
    retryPolicy.Execute(() =>
    {
        // 你的数据库操作代码
    });
    

内容的提问来源于stack exchange,提问作者Christian Cascone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:37:49