谁能解释一下在查询中使用with (nolock)的含义,什么时候应该/不应该使用它?
例如,如果你有一个银行应用程序,有很高的事务率,在某些表中有很多数据,在什么类型的查询中nolock是可以的?在某些情况下,你是否应该总是使用它/永远不要使用它?
谁能解释一下在查询中使用with (nolock)的含义,什么时候应该/不应该使用它?
例如,如果你有一个银行应用程序,有很高的事务率,在某些表中有很多数据,在什么类型的查询中nolock是可以的?在某些情况下,你是否应该总是使用它/永远不要使用它?
当前回答
我使用with (nolock)提示,特别是在SQLServer 2000数据库的高活动。我不确定在SQL Server 2005中是否需要它。我最近应客户端的DBA的请求在SQL Server 2000中添加了这个提示,因为他注意到有很多SPID记录锁。
我所能说的是,使用提示并没有伤害我们,似乎已经使锁定问题解决自己。那个特定客户的DBA坚持让我们使用这个提示。
顺便说一下,我处理的数据库是企业医疗索赔系统的后端,因此我们谈论的是许多连接中的数百万条记录和20多个表。我通常为连接中的每个表添加WITH (nolock)提示(除非它是派生表,在这种情况下,您不能使用该特定提示)
其他回答
简单的答案-当你的SQL没有改变数据时,你有一个可能干扰其他活动的查询(通过锁定)。
对于用于报告的任何查询,都值得考虑,特别是当查询花费的时间超过1秒时。
如果您有针对OLTP数据库运行的olap类型的报告,那么它尤其有用。
第一个要问的问题是“我为什么要担心这个?”根据我的经验,当人们处于“尝试任何东西”模式时,通常会出现捏造默认锁定行为,而这种情况下意外的结果并非不可能发生。通常情况下,这是一个过早优化的情况,并且很容易嵌入到应用程序中“以防万一”。重要的是要了解你为什么要这样做,它解决了什么问题,以及你是否真的有问题。
不幸的是,这不仅仅是读取未提交的数据。在后台,您可能会读两次页面(在页面分割的情况下),或者您可能会完全错过这些页面。所以你的结果可能是严重扭曲的。
看看Itzik Ben-Gan的文章。以下是节选:
" With the NOLOCK hint (or setting the isolation level of the session to READ UNCOMMITTED) you tell SQL Server that you don't expect consistency, so there are no guarantees. Bear in mind though that "inconsistent data" does not only mean that you might see uncommitted changes that were later rolled back, or data changes in an intermediate state of the transaction. It also means that in a simple query that scans all table/index data SQL Server may lose the scan position, or you might end up getting the same row twice. "
问题是什么更糟:
死锁,或者 一个错误的值?
对于金融数据库来说,死锁比错误的值更糟糕。我知道这听起来有点反,但听我说完。DB事务的传统示例是更新两行,从一行中减去一行,向另一行中添加一行。这是错误的。
在财务数据库中使用业务事务。这意味着为每个帐户添加一行。这些事务的完成和行的成功写入是极其重要的。
让账户余额暂时错误不是什么大问题,这就是一天结束的和解。由于同时使用两台atm机,比未从数据库中读取数据更有可能发生帐户透支。
也就是说,SQL Server 2005修复了大部分使NOLOCK成为必要的错误。因此,除非您使用的是SQL Server 2000或更早版本,否则不需要它。
进一步的阅读 行级版本控制
不确定为什么没有在数据库事务中包装金融事务(当您将资金从一个帐户转移到另一个帐户时—您不每次提交事务的一方—这就是显式事务存在的原因)。即使您的代码听起来对业务事务来说是脑死亡,但所有事务性数据库都有可能在发生错误或失败时执行隐式回滚。我觉得这个讨论超出了你的理解力。
如果您遇到了锁定问题,请实现版本控制并清理代码。
没有锁不仅返回错误的值,还返回虚记录和副本。
这是一个常见的误解,它总是使查询运行得更快。如果表上没有写锁,也没有什么区别。如果表上有锁,它可能会使查询更快,但最初发明锁是有原因的。
公平地说,这里有两个特殊的场景,nolock提示可以提供实用程序
1) 2005年以前的sql server数据库需要对实时OLTP数据库运行长查询,这可能是唯一的方法
2)写得很糟糕的应用程序,它锁定记录并将控制权返回给UI和阅读器,无限期地阻塞。如果应用程序无法修复(第三方等),数据库是2005年以前或版本无法打开,Nolock可以在这里提供帮助。
最简单的答案就是一个简单的问题——你需要你的结果是可重复的吗?如果是,那么NOLOCKS在任何情况下都不合适
如果你不需要可重复性,那么nolock可能是有用的,特别是当你不能控制所有连接到目标数据库的进程时。