【发布时间】:2016-07-09 13:47:14
【问题描述】:
我正在测试使用 TransactionScope 以及将隔离级别设置为 ReadUncommitted 的选项来执行特定查询。然而,我看到的是,由于在连接上设置了隔离级别,当连接被重用于其他查询时,隔离级别仍然是 ReadUncommitted 而不是重置为默认的 ReadCommitted。
根据许多建议,我将新的 NoLock 方法抽象为如下扩展:
public static class QueryableExtensions
{
static TransactionScope CreateNoLockTransaction()
{
return new TransactionScope(TransactionScopeOption.Required, new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadUncommitted
});
}
public static T[] ToNoLockArray<T>(this IEnumerable<T> query)
{
using (var ts = CreateNoLockTransaction())
{
return query.ToArray();
}
}
public static List<T> ToNoLockList<T>(this IEnumerable<T> query)
{
using (var ts = CreateNoLockTransaction())
{
return query.ToList();
}
}
public static int NoLockCount<T>(this IEnumerable<T> query)
{
using (var ts = CreateNoLockTransaction())
{
return query.Count();
}
}
}
然后我想验证我在事务范围内和不在事务范围内运行的各种查询的隔离级别。为此,我开始使用查询的上下文执行以下查询:
db.ExecuteQuery<int>("select cast(transaction_isolation_level as int) from sys.dm_exec_sessions where session_id = @@SPID").FirstOrDefault();
在执行 NoLock 扩展方法之前运行上述,返回隔离级别为 2。在运行 NoLock 扩展方法并检查事务范围外查询的隔离级别后,返回 1。
这是否意味着当使用 TransactionScope 更改隔离级别时,受影响的连接在重新用于其他查询和数据上下文时,会继续使用 ReadUncommitted 隔离级别?这是否会破坏使用事务临时更改特定查询的隔离级别的目的,因为它会影响之后的所有查询?
【问题讨论】:
-
离题 - 我相信你知道
READ UNCOMMITTED可以返回脏读。这些可以包括技术上从未属于数据库的记录。 Source - MSDN。更多信息请见this blog entry。 -
对,这正是我只想执行某些查询的原因,这些查询我可以用 READ UNCOMMITTED 隔离级别考虑脏读。问题是在 LINQ to SQL 中实现这一点的解决方案,甚至可能 EF 也会影响其他查询,这是不希望的行为。
-
这一定与位于4 minutes and 7 minutes, 40 seconds之间的连接池中的真实连接有关。
标签: sql-server linq-to-sql transactions isolation-level transaction-isolation