【问题标题】:Setting Transaction Isolation Level in .NET / Entity Framework for SQL Server在 .NET/Entity Framework for SQL Server 中设置事务隔离级别
【发布时间】:2015-09-25 06:11:06
【问题描述】:

我正在尝试在 .NET/C# 中为事务设置事务隔离级别。我正在使用以下代码来设置交易:

 using (var db = new DbContext("ConnectionString"))
 {
     using (var transaction = new TransactionScope(TransactionScopeOption.RequiresNew, 
             new TransactionOptions() { IsolationLevel = IsolationLevel.Snapshot }))
     {
         ...code here

         transaction.Complete();
     }
 }

使用 SQL Server Profiler,这会产生以下结果:

set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed

为什么在我特别请求“快照”时将隔离级别设置为“已提交读”?

已为相关数据库启用快照隔离。

此“已提交读”被另一个长时间运行的事务阻塞。

在长时间运行的事务中,在 SQL Server Management Studio 中运行以下代码可以正常工作,但上面的代码被阻止,因为隔离级别与我指定的不同。

USE <database>;
GO
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
GO
BEGIN TRANSACTION;
GO

<SELECT STATEMENT>

GO
COMMIT TRANSACTION;
GO

为什么?

【问题讨论】:

    标签: c# .net tsql transactions isolation-level


    【解决方案1】:

    new TransactionScope 所做的只是设置Transaction.Current。这就是它所做的 100%。现在,任何想要支持交易的人都可以查看该属性并加入。通常的DbConnection 类在打开时会注册。显然,您的代码在此特定范围内不会打开连接。

    System.Transactions 没有内置支持更改隔离级别(这是一个可悲的遗漏)。你需要自己做。

    【讨论】:

    • 我不确定我是否遵循。似乎您是在说即使 new TransactionScope() 接受 TransactionOptions 的参数,但这些选项没有被使用?这没有任何意义。外部范围(var db)只是一个 DbContext。这不会打开连接吗?有没有办法可以重写它以获得我期望的行为?如何更改事务的隔离级别?
    • "这没有任何意义" 参数将被使用 when Transaction.Current 将被使用。但没有人关注这个价值。您的“外部范围”与交易无关。通常,EF 会为每个 DB 操作打开一个新连接。如果您想了解更多详细信息,请发布更完整的代码。
    • 这基本上是我的完整代码。那是我的问题。我究竟做错了什么?我希望我的 select 语句(如下所述)使用快照事务进行选择。我怎么做? using (var db = new DbContext("ConnectionString")) { using (var transaction = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions() { IsolationLevel = IsolationLevel.Snapshot })) { db.Person.ToList(); transaction.Complete(); } }
    • 好的,在范围内实例化上下文(不太可能修复)。除此之外,这应该有效。也许我们在这里不能完全信任分析器。 TDS 协议有一种方法可以在没有 SQL 的情况下设置隔离级别。也许它没有出现。在范围内执行“select isolevel from sys.sessions where id = @@SPID”以确保。或者,将分析器设置为显示“TM 管理器”事件。
    • 设置分析器以显示 TM 管理器事件没有显示任何内容,但我想我找到了我的问题。我无意中使用了TransactionScopeOption.Suppress 而不是TransactionScopeOption.RequireNew。此外,我将事务块移动到新的 DbContext 块的范围内。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    • 2012-04-22
    相关资源
    最近更新 更多