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

Azure云SQL Server连接遇网络错误:如何用Polly实现连接重试策略

使用Polly实现Azure SQL连接重试策略

哈哈,这个场景我太熟了!Azure SQL偶尔的网络波动或者临时不可用确实会抛出这类连接错误,用Polly来做重试策略完美适配这种 transient(临时)故障场景。下面分两种常见情况给你一步步实现:

1. 先搞定依赖包

首先得把Polly和SQL客户端包装上,现在推荐用Microsoft.Data.SqlClient替代旧的System.Data.SqlClient:

Install-Package Polly
Install-Package Microsoft.Data.SqlClient

2. 定义需要重试的错误范围

不是所有SQL异常都值得重试,我们只针对网络相关的临时错误。你遇到的错误码是40,还有几个常见的Azure SQL transient错误也可以加进去:

private static bool ShouldRetryOnSqlError(SqlException ex)
{
    // 这些是Azure SQL常见的临时网络/连接错误码
    var transientErrorCodes = new HashSet<int> { 40, 233, 10054, 10928, 10929 };
    return ex.Errors.Cast<SqlError>().Any(error => transientErrorCodes.Contains(error.Number));
}

3. 创建Polly重试策略

这里用指数退避策略比固定间隔更合理——第一次重试等1秒,第二次2秒,第三次4秒,既给Azure SQL恢复时间,又不会引发重试风暴:

// 最多重试3次,间隔指数递增
var sqlRetryPolicy = Policy
    .Handle<SqlException>(ex => ShouldRetryOnSqlError(ex))
    .WaitAndRetry(3, retryAttempt => 
        TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

4. 把策略应用到手动连接逻辑

如果你是直接用SqlConnection写连接代码,记得每次重试时要销毁旧连接、创建新的(旧连接可能已经失效):

public async Task<SqlConnection> GetOpenSqlConnectionAsync(string connectionString)
{
    SqlConnection connection = new SqlConnection(connectionString);
    
    await sqlRetryPolicy.ExecuteAsync(async () =>
    {
        try
        {
            if (connection.State != ConnectionState.Open)
            {
                await connection.OpenAsync();
            }
        }
        catch (SqlException)
        {
            // 连接失败后销毁旧连接,避免无效连接占用资源
            connection.Dispose();
            connection = new SqlConnection(connectionString);
            throw; // 抛出异常让Polly触发重试
        }
    });
    
    return connection;
}

5. 用EF Core的话?更简单!

如果你用Entity Framework Core连接Azure SQL,EF Core已经内置了Polly的重试支持,直接配置就行,不用手动写策略:

services.AddDbContext<YourDbContext>(options =>
{
    options.UseSqlServer(connectionString, sqlOptions =>
    {
        sqlOptions.EnableRetryOnFailure(
            maxRetryCount: 3, // 最多重试3次
            maxRetryDelay: TimeSpan.FromSeconds(4), // 最大重试间隔
            errorNumbersToAdd: new[] { 40, 233, 10054 }); // 额外要重试的错误码
    });
});

几个关键注意点

  • 重试次数别设太多,3-5次足够,避免给Azure SQL添负担
  • 指数退避是最优选择,比固定间隔更能应对云环境的波动
  • 如果你的业务操作是幂等的(比如查询、更新操作重复执行不影响结果),可以考虑加入更多transient错误(比如死锁错误码1205)
  • 一定要处理连接对象的生命周期,避免资源泄漏

内容的提问来源于stack exchange,提问作者I Love Stackoverflow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:09:30