选择(nolock)

时间:2014-05-05 07:40:51

标签: sql-server sql-server-2008 select deadlock

我的老板一直强迫我用with (nolock)编写SELECT查询以防止死锁。但是AFAIK,默认情况下Select语句没有锁,因此选择with (nolock)并选择不会没有任何区别。如果我错了,请纠正我。

两个问题:

SELECT * from EMP with (nolock)

SELECT * from EMP 

两者都不一样。如果我没有把nolock放在一边会不会出现死锁?请告诉我应该用什么。

3 个答案:

答案 0 :(得分:3)

非常谨慎地使用Nolocks。对nolock(读取未提交的)提示的最常见理解是它读取尚未提交的数据。但是,还有其他副作用可能非常危险。 (搜索" nolock"和"页面拆分")

这里写得非常好...... http://sqlmag.com/sql-server/beware-nolock-hint

总之," nolocking"所有事情并不总是一个好主意......如果有的话。

答案 1 :(得分:0)

假设我们有默认的事务隔离级别READ COMMITTED,即使在一个非常简单的SELECT语句中也有可能出现死锁。想象一下,User1只读取数据而User2尝试更新一些数据并且非该表上的聚集索引是可能的。

  1. User1正在读取某些数据并获取非聚集索引上的共享锁以执行查找,然后尝试在页面上获取共享锁,以便返回数据本身

  2. 正在编写/更新的User2首先在包含数据的数据库页面上获得一个exlusive锁,然后尝试获取索引的独占锁,以便更新索引。

答案 2 :(得分:0)

SELECT语句的确确实应用了锁,除非查询SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED的顶部没有语句。

总的来说,对于具有聚集索引的表,请在SELECT语句中使用WITH (NOLOCK),但仅在需要时才这样做。

提示:向表中添加聚簇索引的最简单方法是添加一个ID主键列。

结果集可以包含尚未提交的行,这些行通常在以后回滚。

如果将WITH(NOLOCK)应用于具有非聚集索引的表,则在将行数据流式传输到结果表时,其他事务可以更改行索引。这意味着结果集可能缺少行或多次显示同一行。

READ COMMITTED(读取已提交)又增加了一个问题,即数据在单个列中损坏,多个用户同时更改同一单元格。

牢记WITH(NOLOCK)引起的问题将有助于您调整数据库。

对于您的老板来说,只是把他们视为挑战。