【EF 译文系列】韧性连接、重试(EF 版本至少为 6)
2014-04-19 22:23 Sun.M 阅读(1146) 评论(1) 编辑 收藏 举报原文链接:Connection Resiliency / Retry Logic (EF6 onwards)
一个应用程序的数据库连接,是非常容易受其它因素影响的,比如后端的异常或者不稳定的网络连接等。但是,一般在局域网中连接的数据库服务器,这些连接错误是很少发生的,所以处理连接错误的逻辑也就不是必须的。随着越来越多基于云的数据库服务器出现,例如 Window Azure SQL 数据库,如果连接在不可靠的网络环境下,这些连接错误会非常常见。这些可能是由于数据库服务器为了保证服务的公平性而作出的一些保护性处理,比如对连接的限流,或者是不稳定的网络连接导致间歇性的连接超时和一些其它短暂性的错误。
韧性连接,便是指 EF 在执行命令时遇到上诉原因导致连接中断会自动重试执行的一个连接。
执行策略
连接的重试是由 IDbExecutionStrategy 接口的实现来负责, IDbExecutionStrategy 接口的实现会在某个操作出现异常时,来判定是否适合重试,如果适合则会进行重试。EF 提供了 4 种执行策略:
DefaultExecutionStrategy:这个执行策略不会进行任何的重试操作,这是除了 Sql Server 外,其它数据库默认的执行策略。
DefaultSqlExecutionStrategy:这是一个内部默认使用的执行策略,这个策略也不会进行任何的重试操作,但是,它会将这些连接错误的异常包裹起来,并通知用户可能需要开启韧性连接。
DbExecutionStrategy:这个类是一个比较适合用来实现自定义执行策略的基类,它实现了一个指数重试的策略,即,第一次尝试连接时等待为零,后续等待时间以指数级进行增长,直到达到最大尝试次数才终止。这个类有一个抽象方法 ShouldRetryOn ,子类在实现它时,自己决定哪些个异常需要进行重试操作。
SqlAzureExecutionStrategy:这个执行策略继承至 DbExecutionStrategy,它会在 Sql Azure 遇到短暂错误时进行重试操作。
注意:执行策略 2 和 4 包含在 EF 的 Sql Server Provider 中,即 EntityFramework.SqlServer 程序集里。
启用执行策略
告诉 EF 启用执行策略的最简单的方式是使用 DbConfiguration 类的 SetExecutionStrategy 方法:
public class MyConfiguration : DbConfiguration { public MyConfiguration() { SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy()); } }
这段代码告诉了 EF,如果连接到 SQL Server,则将使用 SqlAzureExecutionStrategy 执行策略。
译者注:可使用 DbConfigurationTypeAttribute 特性来标记 DbContext,以启用相应的 DbConfiguration。
配置执行策略
SqlAzureExecutionStrategy 的构造函数可以接受两个参数,MaxRetryCount 和 MaxDelay。MaxRetryCount 是这个执行策略能够重试执行的最大次数,MaxDelay 是一个 TimeSpan 类型,代表从这个策略执行开始最大允许的重试执行时间(即所有重试时间的总和)。
设定最大尝试次数为 1,最大执行延时为 30 秒,则你可以编写如下代码:
public class MyConfiguration : DbConfiguration { public MyConfiguration() { SetExecutionStrategy( "System.Data.SqlClient", () => new SqlAzureExecutionStrategy(1, TimeSpan.FromSeconds(30))); } }
SqlAzureExecutionStrategy 会在第一次出现短暂性错误时,立即进行重试,后续重试的间隔时间将会越来越长,直到超过了最大允许的重试次数,或总共的重试时间超过了最大允许的尝试时间。
执行策略只会在一些常见的短暂性错误导致的异常时,进行重试,也就是说,你还需要自己手动的去处理一些其它错误,以及一些非短暂性错误或很难断定是否为短暂性的错误导致的异常。
局限性
当你使用执行策略时,这里有一些已知的局限性。如果你手动的使用了事务,或使用了流(Stream)替代缓冲(Buffer)进行查询,你可能需要查看更多关于这方面的内容。