5

在过去的一天左右,我一直在尝试在 Azure SQL 数据库上实现瞬态故障处理。尽管我与数据库建立了有效的连接,但我不相信它会按预期处理瞬态故障。

到目前为止,我的方法涉及

public static void SetRetryStratPol()
{
    const string defaultRetryStrategyName = "default";

    var strategy = new Incremental(defaultRetryStrategyName, 3, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
    var strategies = new List<RetryStrategy> { strategy };
    var manager = new RetryManager(strategies, defaultRetryStrategyName);
    RetryManager.SetDefault(manager);
    retryPolicy = new RetryPolicy<SqlDatabaseTransientErrorDetectionStrategy>(strategy);
    retryPolicy.Retrying += (obj, eventArgs) =>
                            {
                                var msg = String.Format("Retrying, CurrentRetryCount = {0} , Delay = {1}, Exception = {2}", eventArgs.CurrentRetryCount, eventArgs.Delay, eventArgs.LastException.Message);
                                System.Diagnostics.Debug.WriteLine(msg);
                            };
}

Global.asax我从's,中调用该方法Application_Start()。[retryPolicy是静态类上的全局静态变量,它也包括下一个方法。]

然后我有一个方法

public static ReliableSqlConnection GetReliableConnection()
{
    var conn = new ReliableSqlConnection("Server=...,1433;Database=...;User ID=...;Password=...;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;", retryPolicy);

    conn.Open();

    return conn;
}

然后我用这个方法

using (var conn = GetReliableConnection())
using (var cmd = conn.CreateCommand())
{
    cmd.CommandText = "SELECT COUNT(*) FROM ReliabilityTest";

    result = (int) cmd.ExecuteScalarWithRetry();

    return View(result);
}

到目前为止,这行得通。然后,为了测试重试策略,我尝试使用错误的用户名(来自这里的建议)。

但是当我单步执行该代码时,光标会立即跳转到我的catch语句

用户“[我的用户名]”登录失败。

我原以为这个异常只会在几秒钟后被捕获,但根本不会产生延迟。

此外,我也尝试过使用实体框架,完全按照这篇文章,但得到了相同的结果。

我错过了什么?是否有配置步骤,或者我是否错误地引发了瞬态故障?

4

1 回答 1

11

瞬态故障处理块用于处理瞬态错误。由于用户名/密码错误而导致登录失败肯定不是其中之一。从这个网页: http: //msdn.microsoft.com/en-us/library/dn440719%28v=pandp.60%29.aspx

什么是瞬态故障?

当应用程序使用服务时,可能会由于临时条件(例如间歇性服务、基础设施级故障、网络问题或服务的显式限制)而发生错误;这些类型的错误在基于云的服务中更频繁地发生,但也可能在本地解决方案中发生。如果您稍后(可能仅在几毫秒后)重试该操作,则该操作可能会成功。这些类型的错误条件称为瞬态故障。瞬态故障通常很少发生,并且在大多数情况下,只需重试几次即可使操作成功。

您可能需要检查此应用程序块 ( http://topaz.codeplex.com/ ) 的源代码,并查看从 SQL 数据库返回的哪些错误代码被视为暂时错误并因此重试。

您始终可以扩展功能并将登录失败作为临时错误之一来测试您的代码。

更新

看看这里的源代码:http: //topaz.codeplex.com/SourceControl/latest#source/Source/TransientFaultHandling.Data/SqlDatabaseTransientErrorDetectionStrategy.cs。这就是重试魔法发生的地方。你可以做的是创建一个类(我们称之为它CustomSqlDatabaseTransientErrorDetectionStrategy)并将整个代码从链接复制到这个类)。然后出于测试目的,您可以将login failed场景添加为瞬态错误之一,并在您的应用程序中使用此类而不是SqlDatabaseTransientErrorDetectionStrategy.

于 2015-01-06T11:08:42.277 回答