多粒度锁协议

描述

每个尝试锁定节点Q的事务必须遵守如下6个规则:

  1. 事务必须遵守锁兼容函数;
  2. 事务必须首先锁定树根节点,且可用任何模式锁定;
  3. 只有将Q节点的父节点锁定在IX或者IS模式时,才能将节点Q锁定在S模式或者IS模式;
  4. 事务只有将Q节点的父节点锁定在IX模式或者SIX模式时,才能将节点Q锁定在X模式或者IX模式或者SIX模式;
  5. 事务只有之前没有解锁任何一个节点时,才能锁定一个节点;
  6. 事务只有没有持有Q的任何子节点时,才能解锁节点Q;

适用范围

  1. 仅要访问若干个数据项的短时事务;
  2. 从一整个文件或者若干个文件集中生成报告的长时事务;

示例

示例1

  • 假设事务已经显式地锁住了文件;
  • 事务想锁住文件中的记录;;
  • 事务想给整个数据库加锁;

分析:

  • 由于事务已经显式地锁住了文件,则记录就被隐式地锁住了;
  • 事务想获取记录的锁,且记录没有被显式地锁住,则需要遍历从树根到记录。如果任何一个节点被以不兼容的模式锁住了,则事务就得等待;
  • 根据多粒度锁协议规则2,事务直接给数据库加上锁即可;
    多粒度锁协议_第1张图片
    数据项多粒度层级树示例1.png

    说明:
  • 一个事务可以给一个节点加共享锁或者排他锁;
  • 当一个事务给一个节点加上某种常规锁时,则该事务已经隐式地给这个节点的后代都加上相同模式的锁了;

    如果事务得到了文件的一把显式排他锁,则该事务已经将属于文件的所有记录锁定在排他锁模式了,这样事务并不需要显式地获取文件的锁了;

示例2 假设

  • 事务为读取在表R中的Andy记录;
  • 事务要更新在表R中的Matt记录;
    则加锁示意图如下:
    多粒度锁协议_第2张图片
    多粒度锁协议示例2.png

示例3 假设

  • 事务为扫描表R,并更新若干个记录;
  • 事务为读取表R中的一个记录;
  • 事务为读取表R中的所有记录;
    则加锁示意图如下:
    多粒度锁协议_第3张图片
    多粒度锁协议示例3.png

应用技巧

一个SQL查询可能需要获取的锁数量可根据该查询要执行的表遍历操作来估计。比如,一个表扫描要获取表级别的锁,但期望获取若干个记录的索引扫描可能要获取表级别的意图锁和记录级别的常规锁。

如果一个事务需要获取大量的记录锁,则锁表数据结构可能会溢出。可通过使用一个表锁来取代大量的记录锁来避免锁表溢出,其实这是一种锁的升级操作。

你可能感兴趣的:(多粒度锁协议)