Entity Framework 6 不使用快照隔离级别。

4
我将尝试将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();
}

我曾经看到有人通过 new 事务的方式显式地设置事务隔离级别,但是我希望将快照隔离作为默认的事务类型,比如在我的 DbContext 的 OnModelCreating 重写中。这是否可能?或者总是需要在显式事务中进行操作?我们使用 Unity IoC 来注入我们的 DbContext,目前在代码中没有声明任何显式事务...


你正在使用EF的Code-First吗?你能将SQL连接传递给你的DbContext构造函数吗? - Evk
我正在使用Unity IoC,如下所示:container.RegisterType<IMyDbContext,MyDbContext>(); - Andy
我将带有 SQL "select case" 的 Linqpad 脚本移入了我的应用程序,但它仍然显示为 "Readcommitted"。 - Andy
通过以下方式可以实现快照隔离,但如果存在全局默认设置的话,我想要使用它: using (var trans = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.Snapshot })) { // 查询语句在此处 } - Andy
是的,我理解您的意思,甚至花了一些时间尝试找到方法,但不幸的是没有结果。 - Evk
显示剩余3条评论
1个回答

4
当你使用SET READ_COMMITTED_SNAPSHOT ON时,所有在READ COMMITTED下运行的事务都将使用SQL Server的行版本控制。在SQL Server中,默认的隔离级别是READ COMMITTED。这意味着除非你的应用程序指定了不同的隔离级别(如早期版本的Entity Framework),否则使用SET READ_COMMITTED_SNAPSHOT ON将立即让你的应用程序使用行版本控制。换句话说,在使用SET READ_COMMITTED_SNAPSHOT ON时,READ COMMITTED是你想要使用的隔离级别。
当你使用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与结合SET ALLOW_SNAPSHOT_ISOLATION ONSNAPSHOT隔离级别之间存在差异。虽然这两种方法都可以让你的事务使用SQL Server的行版本控制,但存在着重大的行为差异。 Read committed Snapshot VS Snapshot Isolation Level

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接