ADO.Net IsolationLevel.Snapshot 与 SET READ_COMMITTED_SNAPSHOT ON

Posted

技术标签:

【中文标题】ADO.Net IsolationLevel.Snapshot 与 SET READ_COMMITTED_SNAPSHOT ON【英文标题】:ADO.Net IsolationLevel.Snapshot with SET READ_COMMITTED_SNAPSHOT ON 【发布时间】:2013-01-16 18:58:08 【问题描述】:

我很好奇在数据库上使用 IsolationLevel.Snapshot 和 SET READ_COMMITTED_SNAPSHOT ON 的效果。 IsolationLevel 枚举的documentation 记录了快照隔离的行为,这不是我们在我们的情况下要寻找的。​​p>

启用 READ_COMMITTED_SNAPSHOT 后,我们应该指定 IsolationLevel.Unspecified,还是根本不提供此值?或者,如果我们确实指定了 IsolationLevel.Snapshot,我们会实现启用 READ_COMMITTED_SNAPSHOT 的预期行为吗?

谢谢!

【问题讨论】:

【参考方案1】:

如果您在数据库级别启用了 read_committed_snapshot,那么所有查询都将具有该默认隔离级别,除非被修改。

如果您更改查询本身的隔离级别,则查询将使用您修改它的隔离级别。

【讨论】:

明白。我想我的问题确实是 LLBLGen 的问题。该工具需要在构造 Transaction 实例时提供 IsolationLevel。需要了解什么值会导致库使用数据库上的默认值。【参考方案2】:

我使用 SQL 2008 R2 和 Entity Framework 4 完成了以下测试。 (数据库的 READ_COMMITTED_SNAPSHOT 选项为 ON)

我创建了以下存储过程来返回上下文隔离级别(来自here):

Create Procedure TempTestIsolation
AS 
Begin
  DECLARE   @UserOptions TABLE(SetOption varchar(100), Value varchar(100))
  INSERT    @UserOptions
  EXEC('DBCC USEROPTIONS WITH NO_INFOMSGS')

  SELECT    Value
  FROM      @UserOptions
  WHERE     SetOption = 'isolation level'
End

然后我编写了以下测试代码:

static void Main(string[] args)

    var entities = new MyEntities();
    // Execute the SP to get the isolation level
    string level = entities.TempTestIsolation().First().Value;
    Console.WriteLine("Without a transaction: " + level);

    var to = new TransactionOptions()  IsolationLevel = System.Transactions.IsolationLevel.Snapshot ;
    using (var ts = new TransactionScope(TransactionScopeOption.Required, to))
    
        // Execute the SP to get the isolation level
        level = entities.TempTestIsolation().First().Value;
        Console.WriteLine("With IsolationLevel.Snapshot: " + level);
    

    to = new TransactionOptions()  IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted ;
    using (var ts = new TransactionScope(TransactionScopeOption.Required, to))
    
        // Execute the SP to get the isolation level
        level = entities.TempTestIsolation().First().Value;
        Console.WriteLine("With IsolationLevel.ReadCommitted: " + level);
    
    Console.ReadKey();

谁的输出是:

如您所见,当您在 TransactionOptions 中将 IsolationLevel 设置为 Snapshot 时,存储过程在“快照”隔离下执行级别,而 NOT 在“已提交的读取快照”下。

相反,如果您将 IsolationLevel 设置为 ReadCommitted,则它在“Read Committed Snapshot”下执行。

希望对你有帮助。

【讨论】:

以上是关于ADO.Net IsolationLevel.Snapshot 与 SET READ_COMMITTED_SNAPSHOT ON的主要内容,如果未能解决你的问题,请参考以下文章

ADO.NET和.NET的关系?

ADO.NET中主要对象

ADO.NET(课程学习内容)

ado.net总结

Linq和ADO.net的区别

ado.net 和 dapper 之间的交集/联合是啥?