【课堂笔记】《数据库系统概论(第5版)》-第11章:并发控制

第11章:并发控制

允许多个用户同时使用同一个数据库的数据库系统称为多用户数据库系统

多种事务的执行方式

  1. 串行执行

    一次只运行一个事务,当前事务结束之后才可以运行下一个事务;

    无法充分利用系统资源;

  2. 交叉并发方式

    在单处理机系统中,事务的并行执行是这些并行事务的并行操作轮流交叉运行;

    单处理机系统中的并行事务并没有真正地并行运行,但能够减少处理机的空闲时间,提高系统的效率;

  3. 同时并发方式

    多处理机系统中,每个处理机可以运行一个事务,多个处理机可以同时运行多个事务,实现多个事务真正的并行运行;

    最理想的并发方式,但受制于硬件环境;

    更复杂的并发方式机制;

事务并发执行带来的问题

  • 会产生多个事务同时存取同一数据的情况
  • 可能会存取和存储不正确的数据,破坏事务隔离性和数据库的一致性

数据库管理系统必须提供并发控制机制

并发控制机制是衡量一个数据库管理系统性能的重要标志之一

11.1 并发控制概述

事务是并发控制的基本单位

保证事务的ACID特性是事务处理的重要任务

为了保证事务的隔离性和统一性,数据库管理系统需要对并发操作进行正确的调度;

并发操作带来的数据不一致性

  1. 丢失修改

  2. 不可重复读

    1. 重复读取某一个值,前后值不相同
    2. 之前读取过的数据,再读取时被删除了
    3. 之前读取过的数据,再读取时多了一些记录(被其他事务修改)
  3. 读脏数据

    T 1 T_1 T1修改了某项数据, T 2 T_2 T2在这之后读取了其值,之后由于某些原因 T 1 T_1 T1回滚,被其修改的数据恢复原值,这时候 T 2 T_2 T2读取到的数据就称为脏数据;

产生上述三类不一致性的主要原因是并发操作破坏了事务的隔离性;

并发控制就是要用正确的方式调度并发操作,使得每一个用户的事务不受其他事务干扰;

对数据库的应用有时允许某些不一致性,例如有些统计工作涉及数据量很大,读到一些“脏”数据对统计精度没什么影响,可以降低对一致性的要求以减少系统开销;

并发控制的主要技术有:封锁、时间戳、乐观控制法、多版本并发控制;

11.2 封锁

封锁是实现并发控制的一个重要技术

排他锁、写锁、X锁

事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁;

保证其他事务在T释放A上的锁之前不能再读取和修改A;

共享锁、读锁、S锁

若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其它事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁;

保证其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改;

锁的相容矩阵

在这里插入图片描述

11.3 封锁协议

在运用X锁和S锁对数据对象加锁时,需要约定一些规则,这些规则为封锁协议(Locking Protocol);

对封锁方式规定不同的规则,就形成了各种不同的封锁协议,它们分别在不同的程度上为并发操作的正确调度提供一定的保证;

  1. 一级封锁协议

    事务T在修改数据R之前必须先对其加X锁,直到事务结束(commit、rollback)才释放;

    一级封锁协议可防止丢失修改,并保证事务T是可恢复的;

    在一级封锁协议中,如果仅仅是读数据不对其进行修改,是不需要加锁的,所以它不能保证可重复读和不读“脏”数据;

  2. 二级封锁协议

    一级封锁协议加上事务T在读取数据R之前必须先对其
    加S锁,读完后即可释放S锁;

    二级封锁协议可以防止丢失修改和读“脏”数据;

    在二级封锁协议中,由于读完数据后即可释放S锁,所以它不能保证可重复读;

  3. 三级封锁协议

    一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放;

    三级封锁协议可防止丢失修改、读脏数据和不可重复读;

在这里插入图片描述

11.4 活锁和死锁

11.4.1 活锁

事务T1封锁了数据R;

事务T2又请求封锁R,于是T2等待;

T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待;

T4又请求封锁R,当T3释放了R上的封锁之后系统又批准了T4的请求;

T2有可能永远等待,这就是活锁的情形

应采用先来先服务策略;

11.4.2 死锁

事务T1封锁了数据R1;

T2封锁了数据R2;

T1又请求封锁R2,因T2已封锁了R2,于是T1等待T2释放R2上的锁;

接着T2又申请封锁R1,因T1已封锁了R1,T2也只能等待T1释放R1上的锁;

这样T1在等待T2,而T2又在等待T1,T1和T2两个事务永远不能结束,形成死锁

  1. 死锁的预防

    1. 一次封锁法

      事务开始时一次性将所有需要加锁的数据全部加锁;

      扩大了封锁的范围,降低系统并发度;

      难以精确确定需要封锁的数据,只能扩大封锁范围,进一步降低并发度;

    2. 顺序封锁法

      顺序封锁法是预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁;

      问题:

      1. 维护成本

        数据库系统中封锁的数据对象极多,并且随数据的插入、删除等操作而不断地变化,要维护这样的资源的封锁顺序非常困难,成本很高;

      2. 难以实现

        事务的封锁请求可以随着事务的执行而动态地决定,很难事先确定每一个事务要封锁哪些对象,因此也就很难按规定的顺序去施加封锁

    结论

    • 在操作系统中广为采用的预防死锁的策略并不太适合数据库的特点
    • 数据库管理系统在解决死锁的问题上更普遍采用的是诊断并解除死锁的方法
  2. 死锁的诊断与解除

    1. 超时法

      如果一个事务的等待时间超过了规定的时限,就认为发生了死锁;

      优点:

      • 实现简单;

      缺点:

      • 有可能误判死锁
      • 时限若设置得太长,死锁发生后不能及时发现
    2. 等待图法

      用事务等待图动态反映所有事务的等待情况;

      事务等待图是一个有向图G=(T,U);

      T为结点的集合,每个结点表示正运行的事务;

      U为边的集合,每条边表示事务等待的情况;

      若T1等待T2,则T1,T2之间划一条有向边,从T1指向T2;

      并发控制子系统周期性地(比如每隔数秒)生成事务等待图,检测事务。如果发现图中存在回路,则表示系统中出现了死锁;

    解除死锁

    • 选择一个处理死锁代价最小的事务,将其撤消;
    • 释放此事务持有的所有的锁,使其它事务能继续运行下去;

    对撤销的事务的数据修改操作必须加以恢复;

11.5 并发调度的可串行性

11.5.1 可串行化调度

定义

多个事务并发执行是正确的,当且仅当其执行结果与按某一次序串行的执行这些事务时的结果相同,称这种调度策略为可串行化调度

可串行性(Serializability),是并发事务正确调度的准则,一个给定的并发调度,当且仅当它是可串行化的,才认为是正确调度

11.5.2 冲突可串行化调度

冲突操作

是指不同的事务对同一数据的读写操作和写写操作;

同一个事务的两个操作和不同事务的冲突操作是不可以交换的;

一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度Sc’,如果Sc’是串行的,称调度Sc是冲突可串行化的调度;

若一个调度是冲突可串行化,则一定是可串行化的调度;

可用这种方法判断一个调度是否是冲突可串行化的;

冲突可串行化调度是可串行化调度的充分条件,不是必要条件。还有不满足冲突可串行化条件的可串行化调度;

11.6 两段锁协议

数据库管理系统普遍采用两段锁协议的方法实现并发调度的可串行性,从而保证调度的正确性;

协议内容

事务分为两个阶段:第一阶段是获得封锁,也称为扩展阶段,在这个阶段,事务可以申请获得任何数据项上的任何锁,但不能释放任何锁;

第二阶段是释放封锁,也称为收缩阶段,在这个阶段,事务可以释放任何数据项上任何类型的锁,但不能获得任何锁;

事务遵守两段锁协议是可串行化调度的充分条件,而不是必要条件;

若并发事务都遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的

若并发事务的一个调度是可串行化的,不一定所有事务都符合两段锁协议;

11.7 封锁的粒度

封锁对象的大小称为封锁粒度(Granularity);

封锁的对象:逻辑单元,物理单元;

在关系数据库中,封锁对象:

逻辑单元:

  • 属性值
  • 属性值的集合
  • 元组
  • 关系
  • 索引项
  • 整个索引
  • 整个数据库

物理单元:

  • 页(数据页或索引页)
  • 物理记录

封锁粒度与系统的并发度和并发控制的开销密切相关:

  • 封锁的粒度越大,数据库所能够封锁的数据单元就越少,并发度就越小,系统开销也越小;

  • 封锁的粒度越小,并发度较高,但系统开销也就越大;

11.7.1 多粒度封锁

多粒度树

  • 以树形结构来表示多级封锁粒度;
  • 根结点是整个数据库,表示最大的数据粒度;
  • 叶结点表示最小的数据粒度;

允许多粒度树中的每个结点被独立地加锁;

对一个结点加锁意味着这个结点的所有后裔结点也被加以同样类型的锁;

所以,在多粒度封锁中一个数据对象可能以两种方式封锁:显式封锁和隐式封锁;

显式封锁:直接加到数据对象上的封锁;

隐式封锁:是该数据对象没有独立加锁,是由于其上级结点加锁而使该数据对象加上了锁;

显式封锁和隐式封锁的效果是一样的;

造成的结果是,对一个数据项加锁时,不仅要检查这个数据项本身有没有被加锁,还要检查其所有的上级节点和下级节点;

11.7.2 意向锁

为了提高加锁时检查的效率,引入意向锁的概念;

如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;

对任一结点加基本锁,必须先对它的上层结点加意向锁;

IS锁(意向共享锁)

如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁;

IX锁(意向排他锁)

如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁;

SIX锁(共享意向排他锁)

如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即 S I X = S + I X SIX = S + IX SIX=S+IX

例:对某个表加SIX锁,则表示该事务要读整个表(所以要对该表加S锁),同时会更新个别元组(所以要对该表加IX锁);

在这里插入图片描述

在这里插入图片描述

锁的强度:

  • 锁的强度是指它对其他锁的排斥程度;
  • 一个事务在申请封锁时以强锁代替弱锁是安全的,反之则不然;

具有意向锁的多粒度封锁方法

  • 申请封锁时应该按自上而下的次序进行;
  • 释放封锁时则应该按自下而上的次序进行;

例如:事务T1要对关系R1加S锁

  • 要首先对数据库加IS锁;
  • 检查数据库和R1是否已加了不相容的锁(X或IX);
  • 不再需要搜索和检查R1中的元组是否加了不相容的锁(X锁) ;

具有意向锁的多粒度封锁方法的优点

  • 提高了系统的并发度;
  • 减少了加锁和解锁的开销;
  • 在实际的数据库管理系统产品中得到广泛应用 ;
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值