我正在测试使用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隔离级别吗?这是否会破坏使用事务来临时更改特定查询的隔离级别的目的,因为它会影响以后的所有查询?
最佳答案
您需要使用关闭范围
ts.Complete()
查询之后和返回之前