EF 4.0:保存更改重试逻辑

时间:2010-06-11 14:49:00

标签: entity-framework-4

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

技术:
实体框架4.0
.Net 4.0

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);
      }
  }   
}

问题:

如何在发生错误后运行StoreDB.SaveChanges以重新尝试新的数据库上下文? 与Detach / Attach类似的东西可能会派上用场。

提前致谢! 巴特

1 个答案:

答案 0 :(得分:0)

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