我最近将我的项目从 EF5 升级到 EF6。在这个项目中,我有一个定期运行的 Azure 辅助角色,并在 SQL Azure 上启动一个存储过程来更新一堆数据库信息,平均需要 1.5 小时来执行。完成后,辅助角色将使用存储过程的返回结果执行其他任务。
这曾经在 EF5 中完美运行,但在 EF6 中每次都会失败,并出现以下错误之一:
Error A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)
Error The session has been terminated because it has acquired too many locks. Try reading or modifying fewer rows in a single transaction. A severe error occurred on the current command. The results, if any, should be discarded.
我已尝试以下方法来修复该错误:
- 已验证所有存储过程读取均具有
WITH (NOLOCK)
修饰符 - 将 Entity Framework 上下文的超时时间增加到 5 小时
- 删除了已安装的新
SqlAzureExecutionStrategy
并将其恢复为使用DefaultExecutionStrategy
- 删除了存储过程中发生的所有事务
- 确保辅助角色中的此步骤在其自己的上下文中运行
代码示例:
using (var dbContext = new EFEntityContext())
{
// set the timeout to 5 hours
var objectContext = (dbContext as IObjectContextAdapter).ObjectContext;
objectContext.CommandTimeout = 18000; // 5 hours
// update all active curriculums
var result = dbContext.usp_MyLongRunningProd();
// log the results of the operation
Trace.TraceInformation(result);
}
此外,存储过程将大型表读入游标,循环遍历它,并根据每个项目执行分析和数据更改。我不需要游标处于任何类型的事务中,并且没有使用我所知道的事务,除非 EF 正在创建一个事务,而这就是问题所在。
最佳答案
我相信这篇文章可能有答案,但直到今晚我的工作开始后我才会知道。如果成功的话我会更新这个答案:
http://entityframework.codeplex.com/discussions/454994
其中说:
As part of the Connection Resiliency work we changed the default behavior of certain APIs that can produce side effects to start using transactions. We also introduced a way of opting out from this new behavior for the specific cases in which transactions are not supported. You can for instance, in new overloads of Database.ExecuteSqlCommand pass a new enum parameter that disables transactions.
关于entity-framework - EF6 执行长时间运行的存储过程出现超时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20194277/