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

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


当前回答

nolock提示合法使用的教科书示例是针对高更新OLTP数据库的报告采样。

举个热门的例子。如果美国一家大型商业银行想要每小时发布一份报告,寻找城市层面的挤兑的最初迹象,那么nolock查询可以扫描每个城市的现金存取款总和的交易表。对于这样的报告,由回滚更新事务引起的微小百分比的错误不会降低报告的价值。

其他回答

如果你正在处理金融交易,那么你永远不会想要使用nolock。Nolock最适合用于从具有大量更新的大型表中进行选择,并且您不关心所获得的记录是否可能过期。

对于财务记录(以及大多数应用程序中的几乎所有其他记录),nolock会造成严重破坏,因为您可能会从正在写入的记录中读取数据,而得不到正确的数据。

问题是什么更糟:

死锁,或者 一个错误的值?

对于金融数据库来说,死锁比错误的值更糟糕。我知道这听起来有点反,但听我说完。DB事务的传统示例是更新两行,从一行中减去一行,向另一行中添加一行。这是错误的。

在财务数据库中使用业务事务。这意味着为每个帐户添加一行。这些事务的完成和行的成功写入是极其重要的。

让账户余额暂时错误不是什么大问题,这就是一天结束的和解。由于同时使用两台atm机,比未从数据库中读取数据更有可能发生帐户透支。

也就是说,SQL Server 2005修复了大部分使NOLOCK成为必要的错误。因此,除非您使用的是SQL Server 2000或更早版本,否则不需要它。

进一步的阅读 行级版本控制

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

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

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

我使用with (nolock)提示,特别是在SQLServer 2000数据库的高活动。我不确定在SQL Server 2005中是否需要它。我最近应客户端的DBA的请求在SQL Server 2000中添加了这个提示,因为他注意到有很多SPID记录锁。

我所能说的是,使用提示并没有伤害我们,似乎已经使锁定问题解决自己。那个特定客户的DBA坚持让我们使用这个提示。

顺便说一下,我处理的数据库是企业医疗索赔系统的后端,因此我们谈论的是许多连接中的数百万条记录和20多个表。我通常为连接中的每个表添加WITH (nolock)提示(除非它是派生表,在这种情况下,您不能使用该特定提示)

简短的回答:

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

长一点的回答:

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

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

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

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