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

Azure无服务器数据库连接未返回40613错误码问题咨询

为什么应用连接Azure无服务器数据库时捕获不到40613错误码?

我之前处理Azure无服务器SQL数据库时也碰到过一模一样的问题——SSMS能正常拿到40613错误码,但应用里只抛出超时异常,根本抓不到这个关键错误。核心原因主要有两个,咱们逐个拆解:

核心原因分析

1. 连接超时设置太短

Azure无服务器数据库从暂停状态恢复通常需要10-20秒(甚至更久,取决于数据库大小),但SqlConnection的默认连接超时只有15秒。这就导致:数据库还没来得及返回40613错误,应用的连接请求就已经超时了,直接抛出TimeoutException,根本轮不到SqlException被捕获。

而SSMS的默认连接超时一般是30秒以上,所以它能等到数据库返回40613错误。

2. 恢复过程中的底层连接异常

在数据库恢复初期,可能会出现TCP连接中断、资源暂时不可用等情况,这时候ADO.NET可能直接抛出TimeoutException,而不是封装成带错误码的SqlException。

解决方案

针对这两个问题,我们可以通过调整连接配置和优化重试逻辑来解决:

第一步:延长连接超时时间

在你的连接字符串里增加Connection Timeout=60(设置为60秒足够覆盖大部分恢复场景),给数据库足够的时间返回错误码:

Server=tcp:your-server.database.windows.net,1433;Initial Catalog=your-db;Persist Security Info=False;User ID=your-user;Password=your-pass;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=60;

第二步:优化异常捕获与重试逻辑

不仅要捕获SqlException的40613,还要处理TimeoutException,同时加入重试机制(恢复是个过程,一次请求可能不够)。另外,Azure SQL恢复相关的错误码不止40613,建议一起捕获:

public async Task<IDbConnection> GetConnectionAsync()
{
    const int maxRetryAttempts = 3;
    const int retryDelayMs = 5000; // 每次重试等待5秒,给数据库恢复时间
    int attempt = 0;

    while (attempt < maxRetryAttempts)
    {
        var connection = new SqlConnection(_connectionString);
        try
        {
            await connection.OpenAsync();
            return connection;
        }
        catch (SqlException ex)
        {
            // 捕获所有Azure SQL恢复/暂停相关的错误码
            var recoverableErrors = new HashSet<int> { 40613, 40197, 4060, 10928, 10929 };
            if (recoverableErrors.Contains(ex.Number))
            {
                attempt++;
                await Task.Delay(retryDelayMs);
                continue;
            }
            // 非恢复类SQL异常,直接抛出
            throw;
        }
        catch (TimeoutException)
        {
            // 超时也视为可能的恢复中状态,进行重试
            attempt++;
            await Task.Delay(retryDelayMs);
            continue;
        }
        finally
        {
            // 如果连接没成功打开,确保关闭释放资源
            if (connection.State != ConnectionState.Open)
            {
                connection.Close();
            }
        }
    }

    throw new InvalidOperationException("数据库经过多次重试后仍无法建立连接,请检查数据库状态");
}

补充说明

  • 如果你必须使用同步方法(Open()而非OpenAsync()),同步超时会抛出SqlException,错误码为-2,你也可以把这个错误码加入到可重试的集合中。
  • 可以考虑使用Polly这类重试库来更优雅地处理重试逻辑,避免自己编写循环代码。

内容的提问来源于stack exchange,提问作者Lasse Klitgaard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:29:04