2017-08-29 51 views
0

我有呼叫使用EF这样的存储过程需要一些时间来执行(〜60秒):从实体框架6的异常行为调用存储过程

context.Database.ExecuteSqlCommand(
    "myStoredProcedure @param1", 
    new SqlParameter("param1", param1) 
); 

该存储的过程包括两个部分:

  1. 插入新行到表tblSomeTable事后

  2. 计算从多个表中的一些信息是不要包括tblSomeTable

第二个操作是耗时的。当我从SSMS执行此存储过程我可以看到,一个新行程序完成执行这是一个正常的行为之前加入到tblSomeTable,但是,当我使用上述代码然后一个新行中运行相同的确切过程仅当过程完成执行时才会添加tblSomeTable

此外,在程序运行时,我根本无法查询tblSomeTable(均来自EF和SSMS),从我认为锁定tblSomeTable直到过程结束。这是为什么发生?

这是SQL Server 2008的

+0

您的ExecuteSqlCommand工作是否成功?你只想知道在运行命令时你可以看到tblSomeTable中的数据?对? – CodeNotFound

+0

是的,它是的,是的,我只想看到tblSomeTable中的行。 (在过程完成之前) – astralmaster

回答

0

这究竟是为什么?

这并不是异常行为。您看不到插入到tblSomeTable中的数据,因为当您调用context.Database.ExecuteSqlCommand时,会创建一个新的SQL Server事务。这就是documentation说:

如果没有一个现有的本地或环境事务新的事务将被用于执行命令。

,并用于通过EF交易的默认隔离级别是为序列化最高。这意味着任何在事务外部执行的SQL查询都无法看到当事务未提交时当前插入到tblSomeTable中的任何数据。当您的context.Database.ExecuteSqlCommand未完成其工作时,您在SSMS中执行的查询将无法看到数据。

您可以更改隔离级别,但我不建议这样做,如果那唯一的目的是检查什么叫context.Database.ExecuteSqlCommand当你的存储过程做。后

编辑@大卫布朗 - 微软评论:

EF的默认隔离级别为READ COMMITTED,而不是SERIALIZABLE正如我上面所说。无法读取未提交的数据仍然适用。从documentation

定义:

指定语句不能读取已修改但 没有其他事务提交的数据。这可以防止脏读。数据 可以通过当前事务内的单个语句 之间的其他事务进行更改,从而导致不可重复的读取或 幻影数据。该选项是SQL Server的默认值。

+1

注意EF默认情况下不使用可序列化事务。只是正常阅读承诺。 –

+0

@ DavidBrowne- Microsoft感谢。更新了我的答案。 – CodeNotFound

0

上按照documentation

与EF6 Database.ExecuteSqlCommand()默认情况下,开始将在交易包住命令如果一个人不存在

所以你不会看到任何SSMS修改,直到它结束。