Sql server 使用(nolock)选择

Sql server 使用(nolock)选择,sql-server,sql-server-2008,select,deadlock,Sql Server,Sql Server 2008,Select,Deadlock,我的老板一直强迫我用和(nolock)编写选择查询,以防止死锁。但是,默认情况下,Select语句没有锁,因此选择withwith(nolock)和选择with没有任何区别。如果我错了,请纠正我 两个问题: SELECT * from EMP with (nolock) SELECT * from EMP 不是两者都一样。如果我不把锁上,它会很容易死锁吗?请告诉我应该使用什么。假设我们有默认事务隔离级别READ COMMITED,即使在非常简单的SELECT语句中也有可能出现死锁,想象一下

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

两个问题:

SELECT * from EMP with (nolock)

SELECT * from EMP 

不是两者都一样。如果我不把锁上,它会很容易死锁吗?请告诉我应该使用什么。

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

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

  • 正在写入/更新的User2首先在包含数据的数据库页面上获得一个exlusive锁,然后尝试在索引上获得一个排他锁以更新索引


  • 使用NOLOCK时应格外小心。nolock(readuncommitted)提示最常见的理解是它读取尚未提交的数据。然而,还有其他一些副作用可能非常危险。(搜索“nolock”和“页面拆分”)

    这里有一篇非常好的文章


    简言之,“不锁定”一切并不总是一个好主意。。。如果有的话。

    SELECT语句确实会应用锁,除非查询集事务隔离级别READ UNCOMMIT的顶部有一条语句

    对于具有聚集索引的表,请务必在SELECT语句中使用
    和(NOLOCK)
    ,但最好只在需要时使用

    提示:向表中添加聚集索引的最简单方法是添加Id主键列

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

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

    READ COMMITTED增加了另一个问题,即多个用户同时更改同一单元格时,数据在单个列中损坏

    记住(NOLOCK)原因的问题将有助于优化数据库


    至于你的老板,就把他们看作是一种挑战。

    视情况而定。在高插入情况下,使用with(nolock)可能会读取不正确的数据(而不仅仅是过时的数据)。解决实际问题,而不是症状。如果您所做的只是在SSMS中运行太宽(select*)、太大(no WHERE子句)的查询来检查数据(如上面的示例),那么是的,与(nolock)一起使用这里是关于这个主题的另一个好问题,说select查询不执行任何锁定是不正确的,在默认事务隔离级别下,即读取提交的Select查询不会获得资源上的共享锁。使用NOLOCK查询提示时,它根本不需要任何锁。正如Mitch所提到的,当没有锁被获取时,您的查询将为脏读(未提交的数据)打开