在 SQL Server 中,读锁是如何工作的?

cm0*_*007 18 sql-server locking

假设我有以下长时间运行的查询

UPDATE [Table1]
SET [Col1] = 'some value'
WHERE [Col2] -- some clause which selects thousands of rows
Run Code Online (Sandbox Code Playgroud)

并假设在上述查询运行时执行以下查询

SELECT *
FROM [Table1]
Run Code Online (Sandbox Code Playgroud)

第一个查询是否阻止第二个查询运行,直到第一个查询完成?如果是这样,第一个查询会阻止第二个查询在所有行上运行还是仅在 WHERE 子句中涉及的行上运行?

编辑:

假设第二个查询是

SELECT [Col1], [Col2]
FROM [Table1]
WHERE [Col2] -- some clause whose matching elements overlap those from
             -- the clause in the first query and which has additional matching elements
Run Code Online (Sandbox Code Playgroud)

Rem*_*anu 16

我建议您阅读了解 SQL Server 如何执行查询,它解释了读取和写入的工作方式以及锁定的工作方式。

10000 英尺视图如下:

  • 读取操作符读取数据之前获取对它们读取的数据的共享锁
  • 写操作符在修改数据之前获取对他们修改的数据的排他锁
  • 数据锁只是字符串,例如。由数据库和对象读取范围的键的散列。
  • 根据锁兼容性矩阵,锁管理器维护所有授予的锁的列表并检测不兼容性
  • 不兼容的请求被挂起,直到阻止它们的不兼容的授权被释放
  • 运算符使用锁层次结构来声明在更高级别(页或表级别,忽略分区级别选项)读取或更新数据的意图。这允许操作员锁定整个表而无需锁定每一行
  • 锁生存期和范围锁用于强制执行更高的隔离级别

这真的只是冰山一角。题材很广。在您的示例中,没有人可以回答您关于实际锁定什么的问题,因为这取决于许多因素。当然,任何应用程序都不应该发出 a,SELECT * FROM Table1 因为它缺少 WHERE 子句并且正在使用*. 这些都是不好的做法,因为除其他外,它们会导致锁争用。

如果您遇到读锁和写锁,您需要研究行版本控制和快照隔离。阅读了解基于行版本控制的隔离级别