Entity framework 4 EF 4.0:保存更改重试逻辑

Entity framework 4 EF 4.0:保存更改重试逻辑,entity-framework-4,Entity Framework 4,我想为所有实体SaveChanges方法调用实现一个应用程序范围的重试系统 技术: 实体框架4.0 .NET4.0 namespace Sample.Data.Store.Entities{ 公共部分类StoreDB { public override int SaveChanges(System.Data.Objects.SaveOptions选项) { 对于(Int32尝试=1;;) { 尝试 { 返回基本值。保存更改(选项); } 捕获(SqlException

我想为所有实体SaveChanges方法调用实现一个应用程序范围的重试系统

技术:
实体框架4.0
.NET4.0

namespace Sample.Data.Store.Entities{
公共部分类StoreDB
{  
public override int SaveChanges(System.Data.Objects.SaveOptions选项)
{            
对于(Int32尝试=1;;)
{
尝试
{
返回基本值。保存更改(选项);
}
捕获(SqlException SqlException)
{
//增量尝试
尝试++;
//寻找最大尝试
Int32 maxRetryCount=5;
//如果已达到最大重试次数,则抛出错误
如果(尝试==maxRetryCount)
投掷;
//确定是重试还是中止。
如果(!RetryLitmus(sqlException))
投掷;
其他的
休眠(ConnectionRetryWaitSeconds(尝试));
}
}
}
静态Int32 ConnectionRetryWaitSeconds(Int32尝试)
{
Int32 connectionRetryWaitSeconds=2000;
//回退节流
connectionRetryWaitSeconds=connectionRetryWaitSeconds*
(Int32)数学能力(2,尝试);
返回(connectionRetryWaitSeconds);
}
/// 
///从异常中确定执行
///应再次尝试连接的恢复
/// 
///一般例外
///如果需要重试,则为True;如果不需要,则为false
静态布尔RetryLitmus(SqlException SqlException)
{
开关(sqlException.Number)
{
//服务遇到错误
//正在处理您的请求。请重试。
//错误代码%d。
判例40197:
//服务当前正忙。请重试
//请求在10秒后被删除。代码:%d。
判例40501:
//发生传输级别错误时
//正在从服务器接收结果。(提供程序:
//TCP提供程序,错误:0-已建立连接
//已被主机中的软件中止。)
案例10053:
返回(真);
}
返回(假);
}
}   
}
问题是:

发生错误后,如何运行StoreDB.SaveChanges在新的数据库上下文上重试? 类似于分离/连接的东西可能会派上用场

提前谢谢!
Bart

查看SQL Azure的瞬时故障处理框架。它非常通用,并且很容易修改以包含后端的重试逻辑

namespace Sample.Data.Store.Entities {  
    public partial class StoreDB  
    {  
        public override int SaveChanges(System.Data.Objects.SaveOptions options)
        {            
            for (Int32 attempt = 1; ; )
            {

                try
                {
                    return base.SaveChanges(options);
                }
                catch (SqlException sqlException)
                {
                    // Increment Trys
                    attempt++;

                    // Find Maximum Trys
                    Int32 maxRetryCount = 5;

                    // Throw Error if we have reach the maximum number of retries
                  if (attempt == maxRetryCount)
                      throw;

                  // Determine if we should retry or abort.
                  if (!RetryLitmus(sqlException))
                      throw;
                  else
                      Thread.Sleep(ConnectionRetryWaitSeconds(attempt));
              }
          }
      }

      static Int32 ConnectionRetryWaitSeconds(Int32 attempt)
      {
          Int32 connectionRetryWaitSeconds = 2000;

          // Backoff Throttling
          connectionRetryWaitSeconds = connectionRetryWaitSeconds *
              (Int32)Math.Pow(2, attempt);

          return (connectionRetryWaitSeconds);
      }



      /// <summary>
      /// Determine from the exception if the execution
      /// of the connection should Be attempted again
      /// </summary>
      /// <param name="exception">Generic Exception</param>
      /// <returns>True if a a retry is needed, false if not</returns>
      static Boolean RetryLitmus(SqlException sqlException)
      {
         switch (sqlException.Number)
          {
              // The service has encountered an error
              // processing your request. Please try again.
              // Error code %d.
              case 40197:
              // The service is currently busy. Retry
              // the request after 10 seconds. Code: %d.
              case 40501:
              //A transport-level error has occurred when
              // receiving results from the server. (provider:
              // TCP Provider, error: 0 - An established connection
              // was aborted by the software in your host machine.)
              case 10053:
                  return (true);
          }

          return (false);
      }
  }   
}