首页 > 解决方案 > Entity Framework 中的事务范围是否仅对特定连接有效?

问题描述

我在 Web 应用程序中使用实体框架,并且我有一段代码与事务中的数据库进行通信,如下所示:

using (DbContextTransaction transScope = ctx.Database.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
    // some code here.
    transScope.Commit();
}

隔离级别Serializable,从我读取的内容来看,应该是最高级别的隔离,甚至阻止读取在此事务期间已访问的记录(这是我需要的)。

但是,当我通过另一个与 SSMS 的连接访问 SQL Server 时(该事务正在执行中),我能够访问该事务读取的行。

所以,我想知道的是:事务范围和隔离级别是只对当前连接有效,还是对所有到数据库的连接都有效?

已编辑

我要防止的是:

  1. 请求 A 读取数据库中 id 为 1 的记录。C 列的值为 10。
  2. 请求 B 读取数据库中的相同记录。C 列的值为 10。
  3. 请求 A 更新值为 C = 11 的记录。
  4. 请求 B 更新值为 C = 11 的记录。

在这种情况下,最终值将是 11,但应该是 12。

标签: c#sql-serverentity-framework-6

解决方案


事务——或者更准确地说:它们获取和持有的锁——当然是数据库范围的——它们专门设计用于防止其他事务/会话做某些事情。

是的,Serializable隔离级别是“最高”、最严格的隔离级别——如果您的事务读取行并在WHERE子句中使用某些条件,SQL Server 将使用基于范围(S)的共享锁来防止任何其他事务修改(更新、删除甚至插入这些锁定范围)任何数据。

但是:读取事务默认使用共享锁(S),并且这些不会阻止其他事务读取这些行 - 共享锁,顾名思义,可以在读取事务之间共享。


推荐阅读