【发布时间】:2020-03-23 05:43:08
【问题描述】:
为了防止长读取操作阻塞我现有的由 SQL Server 2016 支持的混合 OLTP/报告 Web 应用程序中的短而频繁的写入操作,我想对一些长时间运行的查询使用快照隔离。查询已经被很好地索引了,由于数据量很大,运行时间很长,虽然我以后可能会使用 RCSI,但我想先使用侵入性较小的 Snapshot Isolation。
我的问题是:如何在 C# 中对我的 SELECT 查询启用快照隔离?看来我必须将我的选择查询包装在一个事务中,这感觉完全不对。
List<Cat> cats = new List<Cat>();
TransactionOptions transactionOption = new TransactionOptions
{
IsolationLevel = IsolationLevel.Snapshot
};
using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOption))
{
using (SqlConnection sqlConnection = new SqlConnection(databaseConnectionString))
{
using (SqlCommand sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandText = "proc_Select_A_Billion_Cats";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlConnection.Open();
using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
{
while (sqlDataReader.Read())
{
// SOME CODE HERE can read the Cat object in from data reader
// Add this cat to the collection
cats.Add(cat);
}
}
}
}
}
从http://www.levibotelho.com/development/plugging-isolation-leaks-in-sql-server/ 可以看出,在SQL Server 2014 及以后的版本中,当连接返回池时,隔离级别将被重置,这很好。
但是在 ADO.NET 事务中包装只执行 SELECT 的存储过程是否正确?在 C# 中实现快照隔离没有比这更好的方法吗?
【问题讨论】:
-
您可以通过在 sql 语句中使用
with (nolock)提示来实现相同的行为。
标签: c# sql-server ado.net transactionscope isolation-level