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

SQL Server 六种意向锁

SQLServer 2023-06-05
1010

之前的文章《SQL Server 意向锁》已经介绍过意向锁是怎么形成的。SQL Server 数据库引擎通常必须获取多个级别的锁才能完全保护资源。这组多粒度级别上的锁称为锁层次结构(如下图)。

图一

当我们通过索引查询某一行数据的时候,该行数据将分配共享锁(S)。而行所在的页级和表级将分配意向共享锁(IS),表明其更小粒度存在共享锁,能快速检测锁冲突,如行级别共享锁(如下图)。意向更新锁(IU)与意向排他锁(IX)的形成原理也类似。

图二

以下是2个事务访问同一个底层资源的加锁情况。当2个事务访问低粒度级别的资源时,其加锁过程及上层资源意向锁分配情况。

图三

除了上面提到的3种意向锁,SQL Server 中还有另外3种意向锁:意向排他共享(SIX)、共享意向更新(SIU)、更新意向排他(UIX)。这3种意向锁对大家比较陌生,以下是对这6种锁的描述。

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

共享意向更新 (SIU)

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

更新意向排他 (UIX)

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


光看文字可能不好理解,看看英文原译:

  • shared with intent exclusive (SIX),即共享锁+意向排他锁

  • shared with intent update (SIU) ,即共享锁+意向更新锁

  • Update with intent exclusive (UIX) ,即更新锁+意向排他锁


现在,我们就测试意向排他共享(SIX)、共享意向更新(SIU)、更新意向排他(UIX)是怎么形成的。

    --准备测试数据
    create table tab(id int,name varchar(50))
    go
    insert into tab
    select [object_id],name
    from sys.objects
    go
    create clustered index ix_tab on tab(id)
    go


    意向排他共享 (SIX)

      BEGIN TRAN
      --页面级设置共享锁(S)
      SELECT * FROM TAB WITH(PAGLOCK,HOLDLOCK) WHERE id = 98
      --同一个连接,使页面再加上意向排他锁(IX)
      UPDATE tab SET name = 'Test' WHERE id = 98
      --查看锁请求情况
      SELECT resource_type,resource_description,request_mode,request_status
      FROM sys.dm_tran_locks
      WHERE resource_database_id=DB_ID()
      AND request_session_id=@@SPID
      ORDER BY request_mode,resource_type
      ROLLBACK TRAN

      图四

      意向排他共享锁(SIX)是共享锁(S)与意向排他锁(IX)的结合,上图种 SIX 出现在页面级别上。其中,行级别 key 请求排他锁,是update语句最后的锁。页面级别 page 请求意向排他共享锁(SIX),是select请求的共享锁(S)与update行请求所在页面的意向排他锁(IX)结合而成。表级别 object 请求意向排他锁(IX),是select请求的意向共享锁(IS)与update请求的向排他锁(IX)结合而成(IX是IS的超集,因此只显示IX)。数据库 database 通常请求共享锁(S),不会阻止 DML 操作。


      共享意向更新 (SIU)

        BEGIN TRAN
        --页面级设置意向更新锁IU
        SELECT * FROM TAB WITH(UPDLOCK,HOLDLOCK) WHERE id = 98
        --同一个连接,使页面级加上共享锁(S)
        SELECT * FROM TAB WITH(PAGLOCK,HOLDLOCK) WHERE id = 98
        --查看锁请求情况
        SELECT resource_type,resource_description,request_mode,request_status
        FROM sys.dm_tran_locks
        WHERE resource_database_id=DB_ID()
        AND request_session_id=@@SPID
        ORDER BY request_mode,resource_type
        ROLLBACK TRAN

        图五

        共享意向更新 (SIU)的理解请参考上面的意向排他共享锁(SIX)说明。


        更新意向排他 (UIX)

          BEGIN TRAN
          --页面级设置意向更新锁IU
          SELECT * FROM TAB WITH(UPDLOCK,HOLDLOCK) WHERE id = 98
          --同一个连接,使页面级加上共享锁(S)
          SELECT * FROM TAB WITH(PAGLOCK,HOLDLOCK) WHERE id = 98
          --查看锁请求情况
          SELECT resource_type,resource_description,request_mode,request_status
          FROM sys.dm_tran_locks
          WHERE resource_database_id=DB_ID()
          AND request_session_id=@@SPID
          ORDER BY request_mode,resource_type
          ROLLBACK TRAN

          图六

          更新意向排他 (UIX)的理解请参考上面的意向排他共享锁(SIX)说明。


          意向锁有两种用途:

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

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


          意向锁不能用锁提示的方法进行设置,它是系统自动维护的。用户在访问的资源时,受到系统20多种锁访问控制,更多的锁冲突情况,可看官方的锁矩阵图了解。不仅如此,SQL Server 还有自旋锁(Spinlock)与闩锁(latch),这些锁保证了数据库系统高效地运行着。




          最近文章推荐:


          历史文章推荐:



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

          评论