实体框架处理连接丢失

时间:2013-03-18 11:50:40

标签: frameworks entity

我们的应用程序使用的是EF 5和c#.net 4.5。由于我们的应用程序在世界各地使用一个中央服务器,因此我们遇到了超时和丢失与服务器连接的问题。

目前我们捕获SaveChanges()方法并再次尝试,直到用户取消。我们可以为代码中的各种加载做些什么?

编辑:我尝试了提议的解决方案,但我没有让它正常工作:

public class MyRetryStrategy : ITransientErrorDetectionStrategy
{
    public bool IsTransient(Exception ex)
    {
        if (ex != null && ex is SqlException)
        {
            foreach (SqlError error in (ex as SqlException).Errors)
            {
                switch (error.Number)
                {
                    case 1205:
                        System.Diagnostics.Debug.WriteLine("SQL Error: Deadlock condition. Retrying...");
                        return true;

                    case -2:
                        System.Diagnostics.Debug.WriteLine("SQL Error: Timeout expired. Retrying...");
                        return true;

                    case -1:
                        System.Diagnostics.Debug.WriteLine("SQL Error: Timeout expired. Retrying...");
                        return true;
                }
            }
        }

        if (ex != null && ex is EntityException)
        {
            ex = ex.InnerException;
            foreach (SqlError error in (ex as SqlException).Errors)
            {
                switch (error.Number)
                {
                    case 1205:
                        System.Diagnostics.Debug.WriteLine("SQL Error: Deadlock condition. Retrying...");
                        return true;

                    case -2:
                        System.Diagnostics.Debug.WriteLine("SQL Error: Timeout expired. Retrying...");
                        return true;

                    case -1:
                        System.Diagnostics.Debug.WriteLine("SQL Error: Timeout expired. Retrying...");
                        return true;
                }
            }
        }

        // For all others, do not retry.
        return false;
    }
}

Enity Framework只会抛出EntityExceptions,所以我添加了第二个代码路径。

实际用法:

  RetryPolicy policy = new RetryPolicy<MyRetryStrategy>(5, TimeSpan.FromMilliseconds(1000));
        policy.ExecuteAction(()=>_context.ProductStatuses.Include(x => x.Name.Translations).Load());

永远不会调用MyRetryStrategy中的IsTransient方法,也不会调用重试。我测试了它在通话之前停止了Databse。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

这个样本让我离开了地面。

http://hmadrigal.wordpress.com/2012/04/23/automatic-retries-using-the-transient-fault-handling-from-enterprise-libraries-entlib/

IService(下面)是您自己的自定义实现。

private static void RetryPolityUsingCode(IUnityContainer container, IService service, OutputWriterService writer)
       {
           writer.WriteLine("Begin sample: RetryPolityUsingCode");
           // Define your retry strategy: retry 5 times, starting 1 second apart
           // and adding 2 seconds to the interval each retry.
           var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));

           // Define your retry policy using the retry strategy and the Windows Azure storage
           // transient fault detection strategy.
           var retryPolicy = new RetryPolicy<MyRetryStrategy >(retryStrategy);


           try
           {
               // Do some work that may result in a transient fault.
               retryPolicy.ExecuteAction(service.AMethodIDefinedInMyService);
           }
           catch (Exception exception)
           {
               // All the retries failed.
               writer.WriteLine("An Exception has been thrown:\n{0}", exception);
           }
           writer.WriteLine("End sample: RetryPolityUsingCode");
       }