在.NET / Entity Framework中为SQL Server设置事务隔离级别

3

我正在尝试为.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

为什么?

1个回答

1
所有new TransactionScope做的就是设置Transaction.Current。这就是它所做的全部。现在,任何想要支持事务的人都可以查看该属性并注册。通常的DbConnection类在打开时注册。显然,在此特定范围内,您的代码没有打开连接。 System.Transactions没有内置支持更改隔离级别(这是一个遗憾的疏漏)。您需要自己完成这一点。

我不确定我理解了。你似乎在说,即使新的TransactionScope()接受TransactionOptions参数,但这些选项并没有被使用?这毫无意义。外部范围(var db)只是一个DbContext。这难道不会打开连接吗?有没有办法重写这个代码以获得我期望的行为?如何更改事务的隔离级别? - log4code
好的,在作用域内实例化上下文(一个不太可能的修复)。除此之外,这应该可以工作。也许我们不能完全信任分析器。TDS协议有一种方法可以在没有SQL的情况下设置隔离级别。也许它不会显示出来。在作用域内执行“select isolevel from sys.sessions where id = @@SPID”以确保。或者,将分析器设置为显示“TM manager”事件。 - usr
我撤回之前的说法...即使使用TrasactionScopeOption.RequireNew仍然能够重现死锁(我知道我以前测试过,这也是为什么它在我的原始代码中的原因)。 - log4code
在范围内执行会话隔离级别查询以确保。 - usr
在这个范围内,它是“快照”,这意味着我还有其他事情要处理,但至少现在我可以把这个勾掉了。谢谢你提供的信息,我之前不知道TDS协议的那些内容。 - log4code
显示剩余3条评论

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