捕获SQL故障转移异常

3
我正在使用NuGet软件包Polly来实现重试逻辑,以捕获故障转移SQL异常。我在Azure中设置了SQL Server Always On高可用性。
与其捕获所有SQL异常(这是不正确的),我想捕获发生故障转移时特定的SQL异常。
从SSMS开始,我显示仪表板,然后能够人为地触发故障转移以测试我的代码。最初,我让所有异常都冒泡(所以没有捕获)。然后我会排队一个故障转移,并查看我的日志以查看引发了哪个SQL异常。随后,我能够捕获由于故障转移而发生的所有SQL异常。
我的问题是,这是一个全面的列表吗?其他实施SQL Server故障转移重试逻辑的人是否还会捕获其他SQL异常?
我已经尝试了接近100次的故障转移逻辑,没有任何异常冒泡。当然,这并不意味着我已经捕获了所有故障转移SQL异常。

重试逻辑包含Policy.Handle<SqlException>(se => IsFailoverSqlException(se))。根据我在代码中何时排队故障转移,我看到下面捕获的三个SQL异常。

    private static bool IsFailoverSqlException(SqlException se)
    {
        return (
                /*
                A network-related or instance-specific error occurred while establishing a connection to SQL Server.
                The server was not found or was not accessible.
                Verify that the instance name is correct and that SQL Server is configured to allow remote connections.
                */
                (se.Class == 20 && se.State == 0 && se.Number == 53) ||
                /*
                Failed while logging Fatal to MT Database: Unable to access availability database 'MedicusMT' because the database replica is not in the PRIMARY or SECONDARY role.
                Connections to an availability database is permitted only when the database replica is in the PRIMARY or SECONDARY role.
                Try the operation again later.
                */
                (se.Class == 14 && se.State == 1 && se.Number == 983) ||
                // A transport-level error has occurred when receiving results from the server.  (provider: Session Provider, error: 19 - Physical connection is not usable)
                (se.Class == 20 && se.State == 0 && se.Number == -1)
            );
    }

1
微软在这里对“瞬态错误”做了一些工作:https://github.com/Azure/elastic-db-tools/blob/master/Src/ElasticScale.Client/ElasticScale.Common/TransientFaultHandling/Implementation/SqlDatabaseTransientErrorDetectionStrategy.cs 函数IsTransient()可以在您的重试逻辑中使用... - HansLindgren
2个回答

0

使用.NET 4.5及以上版本时,行为发生了变化。SqlException Number可能是Win32 API number。我发现错误号取决于SQL Server连接中使用的网络库。

对于命名管道库,您拥有的值很好。 当与Azure库通信时,需要处理瞬态错误。不要重复对Azure案例的良好分析。 在Windows主机上使用TCP网络库将具有Win32内部异常1225。错误编号:1225,状态:0,类:20

我不喜欢 SqlException Net45 的变化,因为 SqlException.Number 是一个值的混合域。它可以是 SQL Server 错误Azure 瞬态错误 或来自底层网络库的 Win32 API。

如果您在工作单元级别应用策略,请考虑重试死锁受害者 SQL Server 错误 1205

如果您进行实时升级,您可能会发现 DBA 会终止 PSID 错误编号:596,状态:1,类别:21


-1

连接状态不会告诉您有关第2种情况和“无法访问...”的任何信息 - 只有当您向不再是sql实例上主数据库的特定数据库执行操作时,才会发生此错误。 - Stephan Møller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接