[英]Calling stored procedure from Entity Framework 6 abnormal behavior
我有一个存储过程需要花费一些时间(〜60秒)才能执行,我使用EF这样调用它:
context.Database.ExecuteSqlCommand(
"myStoredProcedure @param1",
new SqlParameter("param1", param1)
);
存储过程由两部分组成:
在表tblSomeTable
插入新行,然后
从不包含tblSomeTable
多个表中计算一些信息。
第二项操作很耗时。 当我从SSMS执行此存储过程时,我可以看到在过程完成执行之前将新行添加到tblSomeTable
,这是正常现象,但是,当我使用上述代码运行相同的确切过程时,则tblSomeTable
的新行是仅在过程完成执行时添加。
另外,在过程运行时,我无法从tblSomeTable
上查询到tblSomeTable
(都来自EF和SSMS),因为我假设tblSomeTable
上tblSomeTable
放置了锁,直到过程完成为止。 为什么会这样呢?
这是在SQL Server 2008上。
为什么会这样呢?
这不是异常行为。 您看不到插入到tblSomeTable
的数据,因为在调用context.Database.ExecuteSqlCommand
时,将创建一个新的SQL Server事务。 这就是文档所说的:
如果不存在本地事务或环境事务,则将使用新事务执行命令。
EF用于事务的默认隔离级别是最高的,即Serializable 。 这意味着在未提交事务时,在事务外部执行的任何SQL查询都看不到当前插入到tblSomeTable
任何数据。 当context.Database.ExecuteSqlCommand
未完成其工作时,该数据对于在SSMS中执行的查询不可见。
您可以更改隔离级别,但是如果这样做的唯一目的是在调用context.Database.ExecuteSqlCommand
时检查存储过程在做什么,则我不建议您这样做。
@David Browne之后编辑 -微软评论:
EF的默认隔离级别是READ COMMITTED,而不是如上所述的SERIALIZABLE 。 无法读取未提交的数据仍然适用。
文档中的定义:
指定语句无法读取已被其他事务修改但未提交的数据。 这样可以防止脏读。 数据可以被当前事务中各个语句之间的其他事务更改,从而导致不可重复的读取或幻象数据。 此选项是SQL Server的默认选项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.