谁能解释一下在查询中使用with (nolock)的含义,什么时候应该/不应该使用它?

例如,如果你有一个银行应用程序,有很高的事务率,在某些表中有很多数据,在什么类型的查询中nolock是可以的?在某些情况下,你是否应该总是使用它/永远不要使用它?


当前回答

另一种通常可以接受的情况是在报告数据库中,其中的数据可能已经老化,不会发生写入操作。但是,在这种情况下,管理员应该通过更改默认隔离级别在数据库或表级别设置该选项。

在一般情况下:当你非常确定可以读取旧数据时,你可以使用它。重要的是要记住这很容易出错。例如,即使在编写查询时没有问题,但您确定将来数据库中不会有什么变化使这些更新变得更重要吗?

我还想说的是,在银行应用程序或库存应用程序中,这可能不是一个好主意。

其他回答

NOLOCK相当于READ UNCOMMITTED,但是微软说你不应该在UPDATE或DELETE语句中使用它:

对于UPDATE或DELETE语句:此功能将在Microsoft SQL Server的未来版本中删除。避免在新的开发工作中使用此特性,并计划修改当前使用此特性的应用程序。

http://msdn.microsoft.com/en-us/library/ms187373.aspx

本文适用于SQL Server 2005,因此如果您使用的是该版本,就会支持NOLOCK。为了保证你的代码不受未来的影响(假设你决定使用脏读),你可以在你的存储过程中使用这个:

设置事务隔离级别读未提交

简单的答案-当你的SQL没有改变数据时,你有一个可能干扰其他活动的查询(通过锁定)。

对于用于报告的任何查询,都值得考虑,特别是当查询花费的时间超过1秒时。

如果您有针对OLTP数据库运行的olap类型的报告,那么它尤其有用。

第一个要问的问题是“我为什么要担心这个?”根据我的经验,当人们处于“尝试任何东西”模式时,通常会出现捏造默认锁定行为,而这种情况下意外的结果并非不可能发生。通常情况下,这是一个过早优化的情况,并且很容易嵌入到应用程序中“以防万一”。重要的是要了解你为什么要这样做,它解决了什么问题,以及你是否真的有问题。

您可以在仅读取数据时使用它,并且并不真正关心是否可能返回尚未提交的数据。

它可以在读取操作上更快,但我不能确切地说快多少。

一般来说,我建议不要使用它——读取未提交的数据最多可能会有点混乱。

WITH (NOLOCK)相当于使用READ uncommitted作为事务隔离级别。因此,您可能会读取一个未提交的行,该行随后会被回滚,即从未进入数据库的数据。因此,虽然它可以防止读取被其他操作死锁,但也存在风险。在具有高交易率的银行应用程序中,它可能不是您试图用它解决的任何问题的正确解决方案。

简短的回答:

对于有聚集索引的表,只能在SELECT语句中使用WITH (NOLOCK)。

长一点的回答:

WITH(NOLOCK)经常被用作加速数据库读取的神奇方法。

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

如果WITH(NOLOCK)应用于具有非聚集索引的表,那么行索引可以由其他事务更改,因为行数据正在流到结果表中。这意味着结果集可能缺少行或多次显示同一行。

READ COMMITTED增加了一个额外的问题,即多个用户同时更改同一单元格时,单个列内的数据被损坏。