配置弹性设置Entity Framework 6.02

ElT*_*oro 5 .net c# sql database entity-framework

我正在尝试为EF6.02配置弹性设置.我有一个应用程序,它在一个执行点将日志条目写入数据库.应用程序不依赖于SQL服务器,因此如果服务器没有响应,我希望应用程序放弃INSERT查询(通过DbContext的SaveChanges)并立即继续执行.

使用默认设置,调试日志输出十

"在System.Data.dll中发生'System.Data.SqlClient.SqlException'类型的第一次机会异常"

十次尝试后,它会抛出一个异常,我的代码继续.但我想要一次尝试,例如2秒命令超时.根据MSDN上的文档,SQL Server的默认弹性方法是:

DefaultSqlExecutionStrategy:这是默认使用的内部执行策略.此策略根本不会重试,但它会包含任何可能是暂时的异常,以通知用户他们可能希望启用连接弹性.

正如文档中提到的,这种策略根本不会重试.但我还有十次重试.我试图创建一个继承DbConfiguration的类,但我没有找到任何关于如何更改它的文档.

任何人都可以帮我减少重试次数吗?

更新:以下是基于建议的代码

using System;
using System.Data.Entity;
using System.Data.Entity.SqlServer;
using System.Data.Entity.Infrastructure;
using System.Runtime.Remoting.Messaging;

namespace MyDbLayer
{
    public class MyConfiguration : DbConfiguration
    {
        public MyConfiguration ()
        {

          this.SetExecutionStrategy("System.Data.SqlClient", () => SuspendExecutionStrategy
          ? (IDbExecutionStrategy)new DefaultExecutionStrategy()
          : new SqlAzureExecutionStrategy());
        }

        public static bool SuspendExecutionStrategy
        {
            get
            {
                return (bool?)CallContext.LogicalGetData("SuspendExecutionStrategy") ?? false;
            }
            set
            {
                CallContext.LogicalSetData("SuspendExecutionStrategy", value);
            }
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)

并且代码写入SQL

try
    {
        using (MyEntities context = new MyEntities ())
        {
            Log logEntry = new Log();
            logEntry.TS = DateTime.Now;

            MyConfiguration.SuspendExecutionStrategy = true;
            context.Log.Add(logEntry);
            context.SaveChanges();
        }
    }
    catch (Exception ex)
    {
        logger.Warn("Connection error with database server.", ex);
    }
    finally
    {
        //Enable retries again...
        MyConfiguration.SuspendExecutionStrategy = false;
    }
Run Code Online (Sandbox Code Playgroud)

IPS*_*SUS 6

您是否尝试过暂停执行策略

您自己的数据库配置就像这样:

public class MyConfiguration : DbConfiguration 
{ 
    public MyConfiguration() 
    { 
        this.SetExecutionStrategy("System.Data.SqlClient", () => SuspendExecutionStrategy 
          ? (IDbExecutionStrategy)new DefaultExecutionStrategy() 
          : new SqlAzureExecutionStrategy()); 
    } 

    public static bool SuspendExecutionStrategy 
    { 
        get 
        { 
            return (bool?)CallContext.LogicalGetData("SuspendExecutionStrategy") ?? false; 
        } 
        set 
        { 
            CallContext.LogicalSetData("SuspendExecutionStrategy", value); 
        } 
    } 
} 
Run Code Online (Sandbox Code Playgroud)

那么你可以像这样定义不可重复的命令:

public static void ExecWithoutRetry(System.Action action)
{
    var restoreExecutionStrategyState = EbgDbConfiguration.SuspendExecutionStrategy;
    try
    {
        MyConfiguration.SuspendExecutionStrategy = true;
        action();
    }
    catch (Exception)
    {
        // ignore any exception if we want to
    }
    finally
    {
        MyConfiguration.SuspendExecutionStrategy = restoreExecutionStrategyState;
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,具有可重复和不可重试命令的常规数据库代码可能如下所示:

using (var db = new MyContext())
{
    ExecWithoutRetry(() => db.WriteEvent("My event without retries"));
    db.DoAnyOperationWithRetryStrategy();
}
Run Code Online (Sandbox Code Playgroud)