0

我们的应用程序使用的是 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 方法永远不会被调用,也不会调用重试。我测试了它在调用之前停止数据库。

我究竟做错了什么?

4

1 回答 1

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");
       }
于 2014-01-22T14:44:47.923 回答