我正在尝试让 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 ON
和SET 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 快照隔离级别