陷阱SQL故障转移例外

时间:2016-10-13 19:08:27

标签: c# sql-server azure-sql-database alwayson polly

我正在利用NuGet包Polly来实现捕获故障转移SQL异常的重试逻辑。我在Azure中设置了SQL Server Always On High Availability。

我想捕获发生故障转移时发生的特定SQL异常,而不是捕获所有SQL异常(这是不正确的)。

从SSMS,我显示仪表板,然后我能够人工触发故障转移来测试我的代码。最初,我让所有异常都消失了(所以没有陷阱)。然后我会排队故障转移并查看我的日志以查看引发了什么SQL异常。随后,我能够捕获由于故障转移而发生的所有SQL异常。

我的问题是,这是一份全面的清单吗?在SQL Server故障转移中实现重试逻辑的其他人是否会捕获任何其他SQL异常?

我已经尝试了接近100次故障转移的逻辑,没有任何东西冒泡。这当然并不意味着我已经捕获了整个故障转移SQL异常。

重试逻辑有Policy.Handle(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)
            );
    }

2 个答案:

答案 0 :(得分:0)

为什么不简化逻辑并只检查连接状态,如果需要,请创建新连接: conn!= null || conn.State!= ConnectionState.Open

类似于这篇文章:https://technet.microsoft.com/en-us/library/cc917713.aspx#ECAA

答案 1 :(得分:0)

使用NET 4.5及更高版本时,行为已更改。 SqlException Number可能是Win32 API number,我发现错误编号取决于SQL Server连接中使用的网络库。

命名管道库的值很好。 与Azure库通信时,将处理一个暂时性错误。不要在Azure案例中重复一个很好的analysis。 Windows主机上的TCP网络库将具有Win32内部异常1225。错误号:1225,状态:0,类:20

我不喜欢SqlException Net45的更改是SqlException.Number是值的mixed domain。它可以是SQL Server ErrorAzure Transient Error或网络库底层的Win32 API。

如果您在Unit of work级应用该策略,请考虑重试死锁victum SQL Server错误1205

如果进行实时升级,您可能会发现DBA将杀死PSID错误号:596,状态:1,类:21