在事务中或删除表时使用“with nolock”
Posted
技术标签:
【中文标题】在事务中或删除表时使用“with nolock”【英文标题】:using 'with nolock' in transaction or when dropping table 【发布时间】:2019-07-17 09:22:36 【问题描述】:我正在尝试清理临时表。最快的方法是删除或截断表然后回滚并且只包含所需的行。 现在我的问题是数据库的“死锁”。有没有办法使用'with nolock'让数据库不锁定
BEGIN TRANSACTION;
drop table audit.Testing with (nolock) ;
rollback transaction
SELECT *
from
(select *
,rn = ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Id DESC)
FROM audit.testing with (nolock)
) a
where rn =1
order by Id, SysEndTime desc```
【问题讨论】:
【参考方案1】:您处于死锁状态,因为 WITH (NOLOCK) 相当于使用 READ UNCOMMITTED READUNCOMMITTED 指定允许脏读。不发布共享锁来防止其他事务修改当前事务读取的数据,其他事务设置的排他锁不会阻止当前事务读取锁定的数据。允许脏读可能会导致更高的并发性,但代价是读取数据修改,然后由其他事务回滚。这可能会为您的事务产生错误,向用户显示从未提交的数据,或导致用户看到两次(或根本看不到)记录。
READUNCOMMITTED 和 NOLOCK 提示仅适用于数据锁。所有查询,包括带有 READUNCOMMITTED 和 NOLOCK 提示的查询,都会在编译和执行期间获取 Sch-S(模式稳定性)锁。因此,当并发事务在表上持有 Sch-M(模式修改)锁时,查询会被阻止。例如,数据定义语言 (DDL) 操作在修改表的架构信息之前获取 Sch-M 锁。任何并发查询,包括使用 READUNCOMMITTED 或 NOLOCK 提示运行的查询,在尝试获取 Sch-S 锁时都会被阻止。相反,持有 Sch-S 锁的查询会阻塞试图获取 Sch-M 锁的并发事务 microsoft docs
【讨论】:
明白。还有一个问题。如果我删除一个表并回滚,那么只包含我想要的行。但是表有几百万行,查询是否需要很长时间才能完成以上是关于在事务中或删除表时使用“with nolock”的主要内容,如果未能解决你的问题,请参考以下文章