【问题标题】:Why is a NOLOCK query blocking reads/writes?为什么 NOLOCK 查询会阻塞读/写?
【发布时间】:2021-01-22 22:10:23
【问题描述】:

我们在 SQL Server (2016) DB 中有一个视图,它对它选择的所有表使用 NOLOCK 提示。我们发现当这个视图被消费时,它实际上是在阻塞读写。

根据this,NOLOCK 查询会发出 Sch-S 锁,因此只会阻止诸如 DDL 和重新索引作业之类的事情。但是,我们看到 DML 读/写也被阻止,导致我们的整个应用程序出现故障。为什么?

注意:从视图查询中选择不使用 NOLOCK 提示,但如果视图本身使用 NOLOCK,则不确定这是否重要。

注意 2:对事实问题的轻描淡写表示歉意——我在环境中的权限有限,并且很难使用需要提升权限的查询进行调查,因此希望进行纯理论分析。

谢谢!

【问题讨论】:

  • 你如何证明这个视图确实是阻塞的?你有阻塞和阻塞查询的例子吗?被阻止查询的隔离级别是多少?
  • 我还建议拥有适当权限的人下载 sp_whoisactive 并在发生阻塞情况时使用 @get_locks = 1 运行它。它将显示阻塞的查询以及阻塞的对象

标签: sql-server tsql


【解决方案1】:

神话:NOLOCK / READ UNCOMMITTED 表示没有锁

首先,它们是一样的,而且它们确实必须获得一些 锁:

  • 架构稳定性锁 (Sch-S) 可防止表/索引的结构发生变化
  • BULK_OPERATION 锁定堆以防止读取未格式化的页面

而且他们仍然需要使用闩锁才能访问物理页面 内存中的图像,因此仍有一些潜在的阻塞 锁存级别

https://tenbulls.co.uk/2011/10/14/nolock-hits-mythbusters/ https://dba.stackexchange.com/questions/8627/shared-lock-issued-on-isolationlevel-readuncommitted

我已经检查了BULK_OPERATION (HBT [BULK_OPERATION]) 对于没有聚集索引的表很容易复制锁,并且选择没有锁提示。如果存在聚集索引,则不应用 HoBT 锁。

因此,这应该是一种罕见的情况,但仍然有可能使用WITH (NOLOCK) 会阻止其他查询。

【讨论】:

    【解决方案2】:

    来自books online

    NOLOCK 相当于 READUNCOMMITTED。

    不能为被修改的表指定 READUNCOMMITTED 和 NOLOCK 插入、更新或删除操作。 SQL Server 查询优化器 忽略 FROM 子句中的 READUNCOMMITTED 和 NOLOCK 提示 应用于 UPDATE 或 DELETE 语句的目标表。

    NOLOCK 告诉服务器你很乐意读取未提交的数据,允许用户检索数据而不受其他查询设置的锁的影响;这并不意味着“此查询不得锁定表”。

    没有看到您的表格、数据和查询,任何人都只能提供有限的帮助。

    【讨论】:

    • 这是一个视图,它只包含SELECT语句,所以没有修改表。您帖子中链接上的文章说“没有发出共享锁来防止其他事务修改当前事务读取的数据,并且其他事务设置的排他锁不会阻止当前事务读取锁定的数据。”这是我感兴趣的部分。
    • 虽然 SELECT 将(应该)只获得一个共享锁,但可能是服务器升级它并因此阻止对您视图中使用的表的读取和写入。这里有关于调查锁升级的信息:docs.microsoft.com/en-us/troubleshoot/sql/performance/…
    【解决方案3】:

    您确实了解 NOLOCK 意味着您不在乎数据在您读取时是否在事务上是一致的?您知道您可能会遗漏值,或多次读取某些值吗?

    如果您想确保 READERS 不会阻止 WRITERS,请调查并正确了解并发和事务隔离级别并设置适当的级别。在https://docs.microsoft.com/en-us/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide?view=sql-server-ver15阅读它

    【讨论】:

    • 是的——我不在乎数据可能不一致。这是针对汇总报告的,其中轻微的不一致不会产生重大影响。
    【解决方案4】:

    原来确实有一个查询需要 Schema Stability lock,这显然是阻塞了应用程序中的线程。

    【讨论】:

    • 很高兴听到您找到了阻止的原因。
    猜你喜欢
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    相关资源
    最近更新 更多