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

时间:2017-03-30 14:28:48

标签: c# entity-framework transactions

我正在尝试使用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,而且我们目前在代码中的任何地方都没有声明任何显式事务......

1 个答案:

答案 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 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的行版本控制,但是在行为上却存在很大差异: Read committed Snapshot VS Snapshot Isolation Level