EF6 - 处理密集的并发插入操作?

时间:2018-03-23 17:24:39

标签: c# sql-server entity-framework entity-framework-6

我们有一个简单的场景与Sql server数据库交互 - 我们在数据库表中插入一条记录用于特定的日志记录,并且由于数据已经插入,因此永远不会更改。唯一的一点是这种插入操作非常频繁且同时发生。

我们曾经使用存储过程插入并且工作正常。但是,我们最近切换到EF6,我们发现当插入更加密集时,操作更可能最终出现异常:

  

Messsage:已经提出了一个例外,可能是由于a   暂时失败。如果要连接到SQL Azure数据库   考虑使用SqlAzureExecutionStrategy。

     

StackTrace:at   System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute [TResult](Func`1   操作)   System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions   options,Boolean executeInExistingTransaction)at   System.Data.Entity.Internal.InternalContext.SaveChanges()

代码段如下:

using (MyRepository repo = new MyRepository(new MyDbContext()))
{
    var logData = new LogData()
    {
        //Initialize the object
    };
    //Repo.Add adds the object into the context set
    repo.Add(logData);
    //Repo.Complete calls SaveChanges of the context
    repo.Complete();
}

我们已尝试停用AutoDetectChangesEnabled,但它没有改善此案例。 由于这些插入发生在独立的线程中,因此在迭代循环中组织请求的可能性较小。

我想问一下是否有更聪明的方法来调整它?

1 个答案:

答案 0 :(得分:0)

正如异常文本所示,您应该实现SqlAzureExecutionStrategy。只需将此class放置到声明context的同一个程序集中:

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

例外,您的异常可能是由网络问题或与数据库无关的其他问题引起的,在插入操作率非常高的情况下,概率会增加。因此,呈现的配置将在没有您的交互的情况下自行重试失败的请求。您可以阅读更多here