sql-server – SQL Server:跨池连接的隔离级别泄漏

如以前的Stack Overflow问题(TransactionScope and Connection PoolingHow does SqlConnection manage IsolationLevel?)所证明的,事务隔离级别在与SQL Server和ADO.NET(也是System.Transactions和EF,因为它们构建在ADO.NET之上)的池连接中泄漏。

这意味着,在任何应用程序中可能发生以下危险的事件序列:

>发生需要显式事务以确保数据一致性的请求
>任何其他请求不使用显式事务,因为它只进行不严格的读取。此请求现在将作为可序列化执行,可能导致危险的阻塞和死锁

问题:防止这种情况的最好办法是什么?真的需要现在使用显式事务吗?

这里是一个独立的重现。您将看到第三个查询将继承来自第二个查询的可序列化级别。

class Program
{
    static void Main(string[] args)
    {
        RunTest(null);
        RunTest(IsolationLevel.Serializable);
        RunTest(null);
        Console.ReadKey();
    }

    static void RunTest(IsolationLevel? isolationLevel)
    {
        using (var tran = isolationLevel == null ? null : new TransactionScope(0, new TransactionOptions() { IsolationLevel = isolationLevel.Value }))
        using (var conn = new SqlConnection("Data Source=(local); Integrated Security=true; Initial Catalog=master;"))
        {
            conn.Open();

            var cmd = new SqlCommand(@"
select         
        case transaction_isolation_level 
            WHEN 0 THEN 'Unspecified' 
            WHEN 1 THEN 'ReadUncommitted' 
            WHEN 2 THEN 'ReadCommitted' 
            WHEN 3 THEN 'RepeatableRead' 
            WHEN 4 THEN 'Serializable' 
            WHEN 5 THEN 'Snapshot' 
        end as lvl, @@SPID
     from sys.dm_exec_sessions 
    where session_id = @@SPID", conn);

            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    Console.WriteLine("Isolation Level = " + reader.GetValue(0) + ", SPID = " + reader.GetValue(1));
                }
            }

            if (tran != null) tran.Complete();
        }
    }
}

输出:

Isolation Level = ReadCommitted, SPID = 51
Isolation Level = Serializable, SPID = 51
Isolation Level = Serializable, SPID = 51 //leaked!
最佳答案
在SQL Server 2014中似乎已经修复。

在SQL Server版本12.0.2000.8上运行的输出是:

ReadCommitted
Serializable
ReadCommitted

不幸的是,这种改变在任何文档中都没有提及,例如:

> Behavior Changes to Database Engine Features in SQL Server 2014
> Breaking Changes to Database Engine Features in SQL Server 2014

But the change has been documented on a Microsoft Forum.

转载注明原文:sql-server – SQL Server:跨池连接的隔离级别泄漏 - 代码日志