我的老板一直强迫我用with (nolock)
编写SELECT查询以防止死锁。但是AFAIK,默认情况下Select语句没有锁,因此选择with (nolock)
并选择不会没有任何区别。如果我错了,请纠正我。
两个问题:
SELECT * from EMP with (nolock)
SELECT * from EMP
两者都不一样。如果我没有把nolock放在一边会不会出现死锁?请告诉我应该用什么。
答案 0 :(得分:3)
非常谨慎地使用Nolocks。对nolock(读取未提交的)提示的最常见理解是它读取尚未提交的数据。但是,还有其他副作用可能非常危险。 (搜索" nolock"和"页面拆分")
这里写得非常好...... http://sqlmag.com/sql-server/beware-nolock-hint
总之," nolocking"所有事情并不总是一个好主意......如果有的话。
答案 1 :(得分:0)
假设我们有默认的事务隔离级别READ COMMITTED,即使在一个非常简单的SELECT语句中也有可能出现死锁。想象一下,User1只读取数据而User2尝试更新一些数据并且非该表上的聚集索引是可能的。
User1正在读取某些数据并获取非聚集索引上的共享锁以执行查找,然后尝试在页面上获取共享锁,以便返回数据本身
正在编写/更新的User2首先在包含数据的数据库页面上获得一个exlusive锁,然后尝试获取索引的独占锁,以便更新索引。
答案 2 :(得分:0)
SELECT语句的确确实应用了锁,除非查询SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED的顶部没有语句。
总的来说,对于具有聚集索引的表,请在SELECT语句中使用WITH (NOLOCK)
,但仅在需要时才这样做。
提示:向表中添加聚簇索引的最简单方法是添加一个ID主键列。
结果集可以包含尚未提交的行,这些行通常在以后回滚。
如果将WITH(NOLOCK)应用于具有非聚集索引的表,则在将行数据流式传输到结果表时,其他事务可以更改行索引。这意味着结果集可能缺少行或多次显示同一行。
READ COMMITTED(读取已提交)又增加了一个问题,即数据在单个列中损坏,多个用户同时更改同一单元格。
牢记WITH(NOLOCK)引起的问题将有助于您调整数据库。
对于您的老板来说,只是把他们视为挑战。