实体框架 6 未使用快照隔离级别



我正在尝试让 EF 6 的默认事务隔离级别使用快照隔离,但它不起作用,并且始终使用 Readcommitted。 这是我到目前为止所做的:

我已通过执行以下命令在 SQL Server 2014 数据库上启用了 SQL Server 快照隔离:

ALTER DATABASE MyDb
SET READ_COMMITTED_SNAPSHOT ON
GO
ALTER DATABASE MyDb
SET ALLOW_SNAPSHOT_ISOLATION ON
GO

我有一个 DbContext 实现,并编写了以下 Linqpad 脚本来输出正在使用的隔离级别,并且它总是显示"已提交",这很糟糕。 下面是 Linqpad 脚本:

void Main()
{
this.Database.SqlQuery<string>(@"SELECT CASE transaction_isolation_level 
WHEN 0 THEN 'Unspecified' 
WHEN 1 THEN 'ReadUncomitted' 
WHEN 2 THEN 'Readcomitted' 
WHEN 3 THEN 'Repeatable' 
WHEN 4 THEN 'Serializable' 
WHEN 5 THEN 'Snapshot' END AS TRANSACTION_ISOLATION_LEVEL 
FROM sys.dm_exec_sessions 
where session_id = @@SPID
").Single().Dump();
}

我见过人们通过更新事务来显式设置事务隔离级别,但我想将快照隔离设置为默认事务类型,就像在我的 DbContext 中的 OnModelCreate 覆盖中一样。 这可能吗? 还是您总是必须在显式事务中执行此操作? 我们正在使用 Unity IoC 为我们注入 DbContext,并且我们目前没有在代码中的任何位置声明任何显式事务......

当你使用
  • SET READ_COMMITTED_SNAPSHOT ON时,在READ COMMITTED下运行的所有事务都将使用 SQL Server 的行版本控制。READ COMMITTED是 SQL Server 中的默认隔离级别。这意味着,除非应用程序指定了不同的隔离级别(如旧版本的实体 Framwork),否则使用SET READ_COMMITTED_SNAPSHOT ON将立即允许应用程序使用行版本控制。换句话说,READ COMITTED是您在使用SET READ_COMMITTED_SNAPSHOT ON时要使用的隔离级别。

  • 使用SET ALLOW_SNAPSHOT_ISOLATION ON时,现在允许对数据库运行的事务使用SET TRANSACTION ISOLATION LEVEL SNAPSHOT。在SNAPSHOT下运行的事务也将使用 SQL Server 的行版本控制。但是,您必须在应用程序中将隔离级别显式设置为SNAPSHOT

您现在应该明白,您不必同时使用SET READ_COMMITTED_SNAPSHOT ONSET ALLOW_SNAPSHOT_ISOLATION ON,因为它们都是使事务使用 SQL Server 的行版本控制的不同方法。

  • 仅使用SET READ_COMMITTED_SNAPSHOT ON将立即更改应用程序的工作方式,但您不必更改代码。

  • 仅使用SET ALLOW_SNAPSHOT_ISOLATION ON将使您能够更好地控制哪些事务使用 SQL Server 的行版本控制,不会立即更改应用程序的工作方式,但您必须更改代码才能使用它。

在做出决定之前,您应该知道SET READ_COMMITTED_SNAPSHOT ON与使用SNAPSHOT隔离级别与SET ALLOW_SNAPSHOT_ISOLATION ON之间存在差异。虽然这两种方法都允许事务使用 SQL Server 的行版本控制,但存在很大的行为差异: 读取已提交的快照 VS 快照隔离级别

最新更新