暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SQL Server 意向锁

SQLServer 2022-03-21
1307

SQL Server 数据库引擎使用意向锁来确保共享锁(S 锁)或排他锁(X 锁)放置在锁层次结构的底层资源上。 意向锁之所以命名为意向锁,是因为在较低级别锁前可获取它们,因此会通知意向将锁放置在较低级别上。

 

意向锁有两种用途:

  • 防止其他事务以会使较低级别的锁无效的方式修改较高级别资源。

  • 提高SQL Server 数据库引擎在较高的粒度级别检测锁冲突的效率。

意向锁包括意向共享 (IS)、意向排他 (IX) 以及意向排他共享 (SIX)

锁模式

说明

意向共享 (IS)

保护针对层次结构中某些(而并非所有)低层资源请求或获取的共享锁。

意向排他 (IX)

保护针对层次结构中某些(而并非所有)低层资源请求或获取的排他锁。IX 是 IS 的超集,它也保护针对低层级别资源请求的共享锁。

意向排他共享 (SIX)

保护针对层次结构中某些(而并非所有)低层资源请求或获取的共享锁以及针对某些(而并非所有)低层资源请求或获取的意向排他锁。 顶级资源允许使用并发 IS 锁。例如,获取表上的 SIX 锁也将获取正在修改的页上的意向排他锁以及修改的行上的排他锁。 虽然每个资源在一段时间内只能有一个 SIX 锁,以防止其他事务对资源进行更新,但是其他事务可以通过获取表级的 IS 锁来读取层次结构中的低层资源。

意向更新 (IU)

保护针对层次结构中所有低层资源请求或获取的更新锁。仅在页资源上使用 IU 锁。 如果进行了更新操作,IU 锁将转换为 IX 锁。

共享意向更新 (SIU)

S 锁和 IU 锁的组合,作为分别获取这些锁并且同时持有两种锁的结果。例如,事务执行带有  PAGLOCK 提示的查询,然后执行更新操作。带有 PAGLOCK 提示的查询将获取 S 锁,更新操作将获取 IU 锁。

更新意向排他 (UIX)

U 锁和 IX 锁的组合,作为分别获取这些锁并且同时持有两种锁的结果。

我们先看看锁的粒度对应的简单锁层次结构(如下图),SQL Server 可以在不同的级别加锁,如行级别、页级别、表级别、数据库级。

现在,假设我们按聚集索引查询某行或几行数据(如下图),此时相应的行数据将加上共享锁(S),而该行数据所在的页、表,将加上意向共享锁(IS)(排它锁或更新锁同理)。这时候,如果其他事务要访问锁定数据页或者表,需要排它锁(X),则该事务将被堵塞,因为意向锁(IS)与排它锁(X)是冲突的。

官网有一张锁模式的兼容性矩阵,可以查看各种锁模式直接的关系。

刚才提到的是其他事务访问同一个资源出现了冲突导致堵塞。那对于同一个事物,行已经加了共享锁,此时需要进一步更改(部分)数据,那么加锁的过程是什么样的呢?

 

如果需要更改数据,最终是要加上排它锁(X),但是排它锁(X)是与共享锁(S)冲突的。而进程对能对同一个资源同时只能持有一个锁,所有只能释放共享锁(S),再加上排它锁(X),如果直接释放,资源可能被其他进程夺走,这种方法不是好的处理方式。

 

最好的处理方法,首先在表级资源检测是否能获取意向排他共享(SIX),意向排他共享(SIX)与意向共享锁(IS)并不冲突,可直接转换;在页级资源检测是否能获取意向排它锁(IX),意向排它锁(IX)与意向共享锁(IS)并不冲突,可直接转换;在行级别直接转换为排它锁(X)(以上检查已经确认已可以直接加排他锁)。

 

类似地,当进程对表具有共享锁(S)并在该表的行上具有更新锁(U)时会发生共享意向更新(SIU),而当进程对表具有更新锁(U)而对行具有排他锁时会发生更新意向排他(UIX)。

意向锁的目的,是告诉其他访问者,在当前锁层次结构中,下面的某个低级别的粒度正常持有锁,这样可以快速检测冲突,快速进行访问,减少了资源消耗。

文章转载自SQLServer,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论