SQL Server部分锁说明理解

1.各类锁兼容性

  参考于https://www.cnblogs.com/leohahah/p/8465062.html,这里只理清楚了部分我理解的。

 

2.部分锁的理解

框架稳定锁

  数据库在编译和执行查询时使用SCH-S锁,但是无法执行获取该锁的并发DDL操作和并发DML操作。

框架修改锁

  数据库在执行DDL操作时使用该锁,在该锁释放之前,阻止该表外围的所有并发操作。

共享锁

1.说明

T1: select * from table (请想象它需要执行1个小时之久,后面的sql语句请都这么想象)
    T2: update table set column1='hello'

2.过程
     T1运行 (加共享锁)
     T2运行
     If T1 还没执行完
         T2等......
     else
         锁被释放
         T2执行
     endif

更新锁

1.说明

       更新锁只作用于行。

2.过程

图1

右侧窗口未加更新锁,在读一行数据的时间很短,所以对该行的共享锁(S锁)的排队时间可以忽略不计,可以认为有窗口无锁。左窗口第一句查询使用了更新锁(U锁),紧接着更新该行资源,更新锁升级为排他锁(X锁)。前5秒,右侧窗口可以查出更新之前的数据,如图1,接着查出更新之后的数据,如图2。

 

图2

 

图3

如果给右侧语句也加上更新锁(U锁),则右侧窗口的结果会在左侧事务提交后执行,从图3 两个窗口的执行时间上可以看到。PS:因为没办法两个窗口完全同时执行语句,所以右侧时间会短一些。

排他锁

使用排他锁(X 锁)时,任何其他事务都无法修改数据;仅在使用 NOLOCK 提示或未提交读隔离级别时才会进行读取操作。

DML操作虽然是读取和修改的合并,但是只有update才会先加IU、U锁来读取数据,然后修改时转化为IX、X。而删除和插入我们可以认为从一开始就是加的IX、X锁。另外,UPDATE 语句可能根据与一个表的联接修改另一个表中的行。 在此情况下,除了请求更新行上的排他锁之外,UPDATE 语句还将请求在联接表中读取的行上的共享锁(S锁)。

  

图4

图4的执行时间上可以看到在排他锁(X锁)在释放之前,共享锁(S锁)处于等待状态,这时候查询语句需要加上NOLOCK

意向锁

官方描述:数据库引擎使用意向锁来保护锁层次结构的底层资源,以防止其他事务对自己锁住的资源造成伤害,提高锁冲突检测性能。

1.提高锁冲突检测性能:当我们删除A表中id=1000的数据时,会给id=1000的数据加上X锁,这时如果有其他事务要求更新整张表数据,就会先找该表中是否有S锁。这时如果表主键是自增长,则需要消耗999次时间资源,找到id=1000的数据,然后不允许挂S锁。

这时出现了意向锁,当给id=1000的行数据挂上X锁时,会为Page和Object表上挂意向排他锁(IX锁),IX锁和S锁冲突,直接返回结果。

2. 保护锁层次结构:当查询A表某页数据时,理想情况下,同时有用户删除整个表数据,这时,虽然查询在前,但是查出的数据是被删除后的结果。而在有意向共享锁(IS锁)的情况下,数据库引擎先对表挂上IS锁,由于IS锁和X锁冲突,这样避免了数据错误。

共享意向排他锁

如图5所示,在当前数据页挂上了共享意向排他锁。意味当前页与S锁、U锁和X锁冲突,当前页所在表挂上了IX锁,当前表可以挂IS锁,但不允许挂S锁、U锁和X锁及其意向锁。

  

图5

共享意向更新锁

  

图6

       如图6,page同时拥有了S锁和IX锁,在高并发时,该页在某时刻允许查询,但不允许更新。但在此时,Page挂上了SIX锁,但是表挂上的时IX锁,这时候查询,会给表上挂IS锁,不会和IX锁冲突,但是Page上的IX锁会和S锁冲突,所以Page上S锁的状态时wait,此时查询需等待表上该行数据的X锁释放。

原文地址:https://www.cnblogs.com/kekeSummer/p/11697442.html