sql-server - 当我更新/插入一行时,它是否应该锁定整个表?

标签 sql-server locking

我有两个长时间运行的查询,它们都在事务上并访问同一个表,但这些表中的行完全独立。这些查询还根据这些查询执行一些更新和插入。

看来,当这些并发运行时,它们会遇到某种类型的锁,并且会阻止任务完成并在更新其中一行时锁定。我在正在读取的行上使用独占行锁,并且进程上显示的锁是 lck_m_ix 锁。

两个问题:

  1. 当我更新/插入一行时,它会锁定整个表吗?
  2. 可以采取哪些措施来解决此类问题?

最佳答案

通常不会,但这取决于(SQL Server 最常用的答案!)

SQL Server 必须以某种方式锁定事务中涉及的数据。当您执行修改时,它必须锁定表本身中的数据以及任何受影响的索引中的数据。为了提高并发性,服务器可能决定使用几种锁定“粒度”,以允许多个进程运行:行锁、页锁和表锁很常见(还有更多)。锁定的范围取决于服务器决定如何执行给定的更新。让事情变得复杂的是,还有共享锁、独占锁和意向独占锁等分类,它们控制锁定的对象是否可以读取和/或修改。

根据我的经验,SQL Server 主要使用页锁来更改表的一小部分,并且如果表的较大部分(根据统计数据)似乎受到影响,超过某个阈值将自动升级为表锁更新或删除。这个想法是,锁定一个表(一个锁)比获取和管理数千个单独的行或页锁以进行大更新更快。

要了解特定情况下发生的情况,您需要查看查询逻辑,并在运行时检查 sys.dm_tran_locks、sys.dm_os_waiting_tasks 或其他 DMV 中的锁定/阻塞条件。您可能希望发现每个进程中的哪一步到底锁定了什么,以发现为什么一个进程会阻塞另一个进程。

关于sql-server - 当我更新/插入一行时,它是否应该锁定整个表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2248011/

相关文章:

c - 甚至可以为 root 锁定设备?

c# - ASP.NET C# 代码中的互斥释放问题

c++ - 关于自旋锁

sql-server - 使用 where 子句过滤存储过程的结果集

c# - SSIS 2012 : is it possible to pass references to Package Objects to an external assembly?

c# - 连接到 sql server 数据库 mdf 文件而不在客户端机器上安装 sql server?

python - 为什么多处理锁定失败?

c++ - 锁定函数层次结构

sql-server - 为什么这个子查询不会导致错误?

SQL存储过程问题