sql-server - 使用强类型数据集重试 SQL Azure 请求

标签 sql-server azure strongly-typed-dataset

我们最近开始使用 SQL Azure 数据库在 Microsoft Azure 中测试 ASP.NET 应用程序。我们很少会遇到超时和丢失连接的情况。我们现在了解这是基于云的数据库的本质,并且使用 transient 故障处理应用程序 block 是推荐的解决方案。但是,这似乎要求您的代码创建连接并发出访问请求。由于我们使用强类型数据集,因此该逻辑隐藏在 Fill() 内部,例如,在为数据集生成的代码中。我们有实际调用生成代码中的方法的业务对象单元,因此我们有一个地方可以放置重试逻辑,但不想在数百个地方放置相同的代码。

在这种情况下有没有办法使用 TFHAB,或者有没有一种方法可以以不需要太多代码的通用方式合并重试逻辑?

最佳答案

我所做的是有一个名为 TransientError 的静态类,其中包含以下两个静态方法(我从 MSDN 借用了大部分代码):

internal static void Try(DbContext context)
{
    int wait = 800;
    bool retry = true;
    while (retry)
    {
        try
        {
            using (SqlConnection con = new SqlConnection(context.Database.Connection.ConnectionString))
            {
                con.Open();
                using (SqlCommand com = new SqlCommand("declare @i int;", con))
                {
                    com.ExecuteNonQuery();
                }
            }
            retry = false;
        }
        catch (SqlException)
        {
            Clear(context);
            Thread.Sleep(wait);
        }
        catch (Exception)
        {
            retry = false;
        }
        // break after we reach 6.4 secs (for a total as 12 secs)
        if (wait == 6400)
        {
            retry = false;
        }
        wait = wait * 2;
    }
}
private static void Clear(DbContext context)
{
    // This is a client side operation so won't cause an exception
    // with a server side error.
    // If it does fail, probably should throw!
    using (SqlConnection con = new SqlConnection(context.Database.Connection.ConnectionString))
    {
        SqlConnection.ClearPool(con);
    }
}

这解决了暂时性网络错误在连接池中留下“损坏”(且不可重用)连接的问题。

我正在使用 Linq,我的每个访问方法如下所示:

public StructureElement ForId(int elementId)
{
    TransientError.Try(this.context);
    StructureElement element = (from se in this.context.StructureElements
                                where se.Id == elementId
                                select se).FirstOrDefault<StructureElement>();
    return element;
}

使用 TransientError.Try 测试连接(如果出现问题,则会清除 ConnectionPool,然后运行 ​​Linq 查询。如果出现问题,则调用方的异常处理将接管。

其他方法也是可能的 - 仅当实际的 Linq 错误等时才调用 TransientError

它已经投入生产大约一年了,没有出现任何问题。

关于sql-server - 使用强类型数据集重试 SQL Azure 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35295297/

相关文章:

windows - Windows Azure 角色中的 OnStop() 方法和 Stopping 事件有什么区别?

.net - 可为空且类型化的数据集,某处是否有生成器?

.net - 如何获取刚刚插入到 .net 类型化数据集中的行的主键?

sql - SQL Server 中的条件约束

sql-server - SQL Server SORT 顺序与 ASCII 代码顺序不对应

c# - 如何获取刚刚添加到 DataTable 的行的标识?

sql-server - Entity Framework 不会解决与复合主键的 PK-FK 关系?

azure - 验证成功时,Test-AzureRmResourceGroupDeployment cmdlet 返回 Empty

Azure Service Fabric,通过域名访问应用程序

tsql - 为什么我的类型化数据集不像临时表?