Bra*_*ith 8 c# sql-server ado.net transactions isolation-level
我正在执行几个长时间运行的SQL查询作为报告模块的一部分.这些查询是在运行时动态构造的.根据用户的输入,它们可以是单个或多个语句,具有一个或多个参数并在一个或多个数据库表上运行 - 换句话说,它们的形式不容易预料到.
目前,我只是在普通的情况下执行这些陈述SqlConnection
,即
using (SqlConnection cn = new SqlConnection(ConnectionString)) {
cn.Open();
// command 1
// command 2
// ...
// command N
}
Run Code Online (Sandbox Code Playgroud)
因为这些查询(实际上是查询批处理)可能需要一段时间才能执行,所以我担心会阻塞其他用户的读/写表.如果这些报告的数据在批处理执行期间发生变化,则不会出现问题.报表查询永远不应优先于这些表上的其他操作,也不应锁定它们.
对于涉及修改数据的大多数长时间运行/多语句操作,我会使用事务.这里的区别在于这些报告查询不会修改任何数据.我是否可以正确地将这些报告查询包装起来SqlTransaction
以控制它们的隔离级别?
即:
using (SqlConnection cn = new SqlConnection(ConnectionString)) {
cn.Open();
using (SqlTransaction tr = cn.BeginTransaction(IsolationLevel.ReadUncommitted)) {
// command 1
// command 2
// ...
// command N
tr.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
这会实现我想要的结果吗?提交事务是否正确,即使没有修改数据?还有另一种方法吗?
另一种方法可能是针对连接发布:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Run Code Online (Sandbox Code Playgroud)
它实现了相同的意图,而不会弄乱交易.或者您可以WITH(NOLOCK)
在查询中使用表上的提示,这样做的好处就是根本不更改连接.
重要的是,请注意(异常):但是它会被更改(事务,事务范围,显式SET
等),在从池中获取隔离级别时,不会在使用相同的基础连接之间重置隔离级别.这意味着如果您的代码更改了隔离级别(直接或间接),那么您的代码都不知道新连接的隔离级别是什么:
using(var conn = new SqlConnection(connectionString)) {
conn.Open();
// isolation level here could be **ANYTHING**; it could be the default
// if it is a brand new connection, or could be whatever the last
// connection was when it finished
}
Run Code Online (Sandbox Code Playgroud)
这让人WITH(NOLOCK)
很有诱惑力.
归档时间: |
|
查看次数: |
4488 次 |
最近记录: |