我们有一个简单的场景与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
,但它没有改善此案例。
由于这些插入发生在独立的线程中,因此在迭代循环中组织请求的可能性较小。
我想问一下是否有更聪明的方法来调整它?
答案 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。