在 C#/ADO.NET 中为 SELECT 查询实施 SQL Server 2016 快照隔离
Implement SQL Server 2016 Snapshot Isolation in C#/ADO.NET for SELECT queries
为了防止长读操作阻塞我现有的由 SQL Server 2016 支持的混合 OLTP/reporting Web 应用程序中频繁的短写操作,我想在一些长的上使用快照隔离-运行宁查询。这些查询已经很好地建立了索引,并且由于大量数据需要很长时间 运行,虽然我稍后可能会使用 RCSI,但我想从使用侵入性较小的快照隔离开始。
我的问题是:如何在 C# 中对我的 SELECT 查询启用快照隔离?看来我必须将我的 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 及更高版本中,当连接返回池时,隔离级别将被重置,这很好。
但是将只执行 SELECT 的存储过程包装在 ADO.NET 事务中是否正确?有没有比这更好的方法来在 C# 中实现快照隔离?
不,您需要在 BeginTransaction
方法中 set the isolation level:
If a database has been enabled for snapshot isolation but is not
configured for READ_COMMITTED_SNAPSHOT ON, you must initiate a
SqlTransaction using the IsolationLevel.Snapshot enumeration value
when calling the BeginTransaction method.
否则,使用默认的Read Committed
模式,READ
将被修改table的事务阻塞(可能)。
为了防止长读操作阻塞我现有的由 SQL Server 2016 支持的混合 OLTP/reporting Web 应用程序中频繁的短写操作,我想在一些长的上使用快照隔离-运行宁查询。这些查询已经很好地建立了索引,并且由于大量数据需要很长时间 运行,虽然我稍后可能会使用 RCSI,但我想从使用侵入性较小的快照隔离开始。
我的问题是:如何在 C# 中对我的 SELECT 查询启用快照隔离?看来我必须将我的 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 及更高版本中,当连接返回池时,隔离级别将被重置,这很好。
但是将只执行 SELECT 的存储过程包装在 ADO.NET 事务中是否正确?有没有比这更好的方法来在 C# 中实现快照隔离?
不,您需要在 BeginTransaction
方法中 set the isolation level:
If a database has been enabled for snapshot isolation but is not configured for READ_COMMITTED_SNAPSHOT ON, you must initiate a SqlTransaction using the IsolationLevel.Snapshot enumeration value when calling the BeginTransaction method.
否则,使用默认的Read Committed
模式,READ
将被修改table的事务阻塞(可能)。