我正在尝试使用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脚本来输出正在使用的隔离级别,并且它总是显示“Readcommitted”,这是不好的。这是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中的OnModelCreating覆盖中一样。那可能吗?或者您是否总是必须在显式交易中执行此操作?我们正在使用Unity IoC为我们注入DbContext,而且我们目前在代码中的任何地方都没有声明任何显式事务......
答案 0 :(得分:0)
使用SET READ_COMMITTED_SNAPSHOT ON
时,在READ COMMITTED
下运行的所有事务都将使用SQL Server的行版本控制。 READ COMMITTED
是SQL Server中的默认隔离级别。这意味着除非您的应用程序指定了不同的隔离级别(如Entity 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的行版本控制,但是在行为上却存在很大差异:
Read committed Snapshot VS Snapshot Isolation Level