SQL Server 锁机制
锁兼容性图:

一、锁的粒度:

比较需要注意的是RID/KEY、HoBT/PAGE这两对儿的区别,RID和HoBT是针对堆表的,即没有聚集索引的表。
二、锁的模式:

共享锁
共享锁(S 锁)允许并发事务在封闭式并发控制下读取 (SELECT) 资源。 资源上存在共享锁(S 锁)时,任何其他事务都不能修改数据。 读取操作一完成,就立即释放资源上的共享锁(S 锁),除非将事务隔离级别设置为可重复读或更高级别,或者在事务持续时间内用锁定提示保留共享锁(S 锁)。
更新锁
更新锁(U 锁)可以防止常见的死锁。 在可重复读或可序列化事务中,此事务读取数据 [获取资源(页或行)的共享锁(S 锁)],然后修改数据 [此操作要求锁转换为排他锁(X 锁)]。 如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排他锁(X 锁)。 共享模式到排他锁的转换必须等待一段时间,因为一个事务的排他锁与其他事务的共享模式锁不兼容;发生锁等待。 第二个事务试图获取排他锁(X 锁)以进行更新。 由于两个事务都要转换为排他锁(X 锁),并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。
若要避免这种潜在的死锁问题,请使用更新锁(U 锁)。 一次只有一个事务可以获得资源的更新锁(U 锁)。 如果事务修改资源,则更新锁(U 锁)转换为排他锁(X 锁)。
一般情况下更新都是直接获取独占锁的,但是如果被更新的行上已经存在独占锁,那么事务就会尝试先获取S锁,如果有多个会话在请求S锁的队列中,那么当独占锁被释放后就有多个会话获取了S锁并尝试转换为X锁,此时发生死锁,U锁的出现即为了解决此问题。 --这段不是官网的描述,而是我根据MySQL的重复性检测加锁机制推测的。如果官网有关于此类先加S锁再转化X的文章请@我。
排他锁
排他锁(X 锁)可以防止并发事务对资源进行访问。 使用排他锁(X 锁)时,任何其他事务都无法修改数据;仅在使用 NOLOCK 提示或未提交读隔离级别时才会进行读取操作。
数据修改语句(如 INSERT、UPDATE 和 DELETE)合并了修改和读取操作。 语句在执行所需的修改操作之前首先执行读取操作以获取数据。 因此,数据修改语句通常请求共享锁和排他锁。 例如,UPDATE 语句可能根据与一个表的联接修改另一个表中的行。 在此情况下,除了请求更新行上的排他锁之外,UPDATE 语句还将请求在联接表中读取的行上的共享锁。
Ps:在这里官网的解释可能会有歧义,DML操作虽然是读取和修改的合并,但是只有update才会先加IU、U锁来读取数据,然后修改时转化为IX、X。而删除和插入我们可以认为从一开始就是加的IX、X锁。
- 防止其他事务以会使较低级别的锁无效的方式修改较高级别资源。
- 提高数据库引擎在较高的粒度级别检测锁冲突的效率。

数据库引擎在表数据定义语言 (DDL) 操作(例如添加列或删除表)的过程中使用架构修改 (Sch-M) 锁。 保持该锁期间,Sch-M 锁将阻止对表进行并发访问。 这意味着 Sch-M 锁在释放前将阻止所有外围操作。
某些数据操作语言 (DML) 操作(例如表截断)使用 Sch-M 锁阻止并发操作访问受影响的表。
数据库引擎在编译和执行查询时使用架构稳定性 (Sch-S) 锁。 Sch-S 锁不会阻止某些事务锁,其中包括排他 (X) 锁。 因此,在编译查询的过程中,其他事务(包括那些针对表使用 X 锁的事务)将继续运行。 但是,无法针对表执行获取 Sch-M 锁的并发 DDL 操作和并发 DML 操作。
- 使用 Transact-SQL BULK INSERT 语句或 OPENROWSET(BULK) 函数,或者您使用某个大容量插入 API 命令(如 .NET SqlBulkCopy)、OLEDB 快速加载 API 或 ODBC 大容量复制 API 来将数据大容量复制到表。
- TABLOCK指定提示或表大容量加载上的锁表选项设置使用sp_tableoption。
关于键范围锁可以参考官网,或者另一篇博客SQL Server事务隔离级别中对于可序列化读隔离级别的加锁说明。
三、锁升级
- 单个 Transact-SQL 语句在单个无分区表或索引上获得至少 5,000 个锁。
- 单个 Transact-SQL 语句在已分区表的单个分区上获得至少 5,000 个锁,并且 ALTER TABLE SET LOCK_ESCALATION 选项设为 AUTO。
- 数据库引擎实例中的锁的数量超出了内存或配置阈值。
- 如果由于锁冲突导致无法升级锁,则数据库引擎每当获取 1,250 个新锁时便会触发锁升级。
- 使用READ_COMMITTED_SNAPSHOT事务隔离级别。
- 使用SNAPSHOT事务隔离级别。
- 使用READ UNCOMMITTED事务隔离级别。
SQL Server 锁机制的更多相关文章
- SQL Server 锁机制 悲观锁 乐观锁 实测解析
先引入一些概念,直接Copy其他Blogs中的,我就不单独写了. 一.为什么会有锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 1.丢失更新 A,B两个用户读同一数据并进行修改,其中 ...
- 简单理解SQL Server锁机制
多个用户同时对数据库的并发操作时,可能会遇到下面几种情况,导致数据前后不一致: 1,A.B事务同时对同一个数据进行修改,后提交的人的修改结果会破坏先提交的(丢失更新): 2,事务A修改某一条数据还未提 ...
- Sql server锁机制
如何查看锁 了解SQL Server在某一时间点上的加锁情况无疑是学习锁和诊断数据库死锁和性能的有效手段.我们最常用的查看数据库锁的手段不外乎两种: 使用sys.dm_tran_locks这个DMV ...
- [转]了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密_Mr_Indigo的空间
了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密 关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突.当一组数据被某个用户锁定时,除非第一个用户结束修 ...
- 了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密
关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突.当一组数据被某个用户锁定时,除非第一个用户结束修改并释放锁,否则其他用户就无法修改该组数据. 有些数据库,包括SQL Se ...
- 转:sql server锁知识及锁应用
sql server锁(lock)知识及锁应用 提示:这里所摘抄的关于锁的知识有的是不同sql server版本的,对应于特定版本时会有问题. 一 关于锁的基础知识 (一). 为什么要引入锁 当多个用 ...
- SQL SERVER锁(LOCK)知识及锁应用
提示:这里所摘抄的关于锁的知识有的是不同sql server版本的,对应于特定版本时会有问题. 一 关于锁的基础知识 (一). 为什么要引入锁 当多个用户同时对数据库的并发操作时会带来以下数据不一致的 ...
- sql server 锁与事务拨云见日(中)
一.事务的概述 上一章节里,重点讲到了锁,以及锁与事务的关系.离上篇发布时间好几天了,每天利用一点空闲时间还真是要坚持.听<明朝那些事儿>中讲到"人与人最小的差距是聪明,人与人最 ...
- sql server 锁与事务拨云见日(上)
一.概述 讲到sql server锁管理时,感觉它是一个大话题,因为它不但重要而且涉及的知识点很多,重点在于要掌握高并发要先要掌握锁与事务,涉及的知识点多它包括各式各样的锁,锁的组合,锁的排斥,锁延伸 ...
随机推荐
- Kubernetes 弹性伸缩全场景解析 (一)- 概念延伸与组件布局
传统弹性伸缩的困境 弹性伸缩是Kubernetes中被大家关注的一大亮点,在讨论相关的组件和实现方案之前.首先想先给大家扩充下弹性伸缩的边界与定义,传统意义上来讲,弹性伸缩主要解决的问题是容量规划与实 ...
- Docker 快速入门之 Dockerfile
在 Docker 中我们可以从名为 Dockerfile 的文件中读取指令并且自动构建镜像.在本文中,将介绍 Dockerfile 的基本语法以及基本知识. Dockerfile 是什么 Docker ...
- Integer判等的陷阱:你知道Integer内部高速缓冲区IntegerCache吗?
https://blog.csdn.net/magician_Code/article/details/51469101 我们先来看看下面代码的运行情况: public static void mai ...
- Go语言远程执行ssh命令简单封装(支持带交互命令)
使用包:golang.org/x/crypto/ssh 以下封装一个发送命令的Cli结构体 type Cli struct { IP string //IP地址 Username string //用 ...
- Java设计模式之《构建者模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6553374.html 构建者模式,又称建造者模式,将一部负责对象的构建分为许多小对象的构建 ...
- Perl的IO操作(1):文件句柄
文件句柄 文件句柄用来对应要操作的文件系统中的文件,这么说不太严谨,但比较容易理解.首先为要打开的文件绑定文件句柄(称为打开文件句柄),然后在后续的操作中都通过文件句柄来操作对应的文件,最后关闭文件句 ...
- 关于 Cortex-M3 的双堆栈机制
CM3 的堆栈分为两个:主堆栈和进程堆栈. 那么,这两个栈分别在什么情况下使用呢? 我们看一下CM3的控制寄存器(CONTROL):控制寄存器用于定义特权级别,还用于选择当前使用哪个堆栈指针. CON ...
- .Net Core 读取配置文件 appsettings.json
1. 首先些一个类 public class MySettings { public string P1 { get; set; } public string P2 { get; set; } } ...
- 积累一些不太常用的C/C++语言知识(不断更新)
这里积累一些日常编程用得比较少的知识,不断添加. scanf("%c%*c%c",&a,&b); 其中的*表示跳过,本来输入三个数字,结果中间那个读入后被抛弃,a和 ...
- python多线程-共享全局变量
目录 多线程-共享全局变量 多线程-共享全局变量 列表当作实参传递到线程中 总结 多线程-共享全局变量问题 多线程开发可能遇到的问题 测试1 测试2 多线程-共享全局变量 多线程-共享全局变量 imp ...