执行长时间运行的存储过程的EF6会收到超时错误

时间:2013-11-25 13:26:18

标签: entity-framework azure-sql-database entity-framework-6

我最近将我的项目从EF5升级到EF6。在这个项目中,我有一个定期运行的Azure辅助角色,并在SQL Azure上启动存储过程以更新大量数据库信息,并且平均需要1.5小时才能执行。完成后,worker角色将使用存储过程的返回结果执行其他任务。

这曾经在EF5中完美运行,但在EF6中,每次出现以下错误都会失败:

  

错误从服务器接收结果时发生传输级错误。 (提供者:会话提供者,错误:19 - 物理连接不可用)

     

错误会话已终止,因为它已获取太多锁。尝试在单个事务中读取或修改较少的行。当前命令发生严重错误。结果(如果有的话)应该被丢弃。

我已尝试以下方法来修复错误:

  1. 验证所有存储过程读取都具有WITH (NOLOCK)修饰符
  2. 将实体框架上下文的超时时间增加到5小时
  3. 删除了已放置的新SqlAzureExecutionStrategy并将其恢复使用DefaultExecutionStrategy
  4. 删除了存储过程中发生的所有事务
  5. 确保辅助角色中的此步骤在其自己的上下文中运行
  6. 代码示例:

    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正在制作一个,这就是问题。

1 个答案:

答案 0 :(得分:2)

我相信这篇文章可能有答案但我不知道,直到今晚我的工作开始。如果成功,我会更新这个答案:

http://entityframework.codeplex.com/discussions/454994

其中说:

  

作为Connection Resiliency工作的一部分,我们更改了默认值   可能产生副作用的某些API的行为开始使用   交易。我们还介绍了一种选择退出这种新方式的方法   交易不具体的特定情况的行为   支持的。例如,你可以在新的重载中使用   Database.ExecuteSqlCommand传递一个禁用的新枚举参数   交易。

相关问题