数据库系统概论:第十一章 并发控制

事务可以一个一个地串行执行,即每一个时刻只有一个事务正在运行,其他事务必须等迭代这个事务结束才能执行。

在单处理机中,事务的并发执行实际上是这些并行事务的并行操作轮流交叉运行。虽然单处理机系统中的并行事务并没有真正地并行,但是减少了处理机的空闲时间,提高了系统地效率。

在这里插入图片描述

11.1 并发控制概述

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

并发控制的目的:保证事务的隔离性和一致性

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

  1. 丢失修改:读入同一数据并修改
  2. 不可重复读:读第一次和读第二次的结果不一样,因为别人在中间修改插入删除了某些数据
  3. 读“脏”数据:T1修改某一数据并写回,T2读取,T1撤销操作,T2的数据便是脏数据

原因:并发操作破坏了事务的隔离性

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

并发控制的主要技术:

  1. 封锁:银行、证券
  2. 时间戳
  3. 乐观控制法
  4. 多版本并发控制

封锁是一种悲观的技术,认为冲突总在发生,因此控制并发事务。23是乐观的技术,认为冲突不常发生,如果冲突再回滚。

11.2 封锁

基本封锁类型:

  • 排他锁 (X锁):写锁

    若事务T对数据对象A加上了X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁为止。这就保证了其他事务在T释放A上的锁之前不能读取和修改A。

  • 共享锁 (S锁):读锁

    若事务T对数据对象加上了S锁,则事务T可以读取A但不能修改A。其他事务也只能再对A添加S锁,而不能加X锁,知道T释放A上的S锁为止。

11.3 封锁协议

  1. 一级封锁协议:事务T在修改数据R前必须先对其加X锁,直到事务结束才释放。

    只能保证不发生丢失修改。

  2. 二级封锁协议:在一级封锁协议基础上,增加事务T在读取数据R前必须先对其加S锁,读完后即可释放S锁。

    保证了不发生读“脏”数据和不发生丢失修改

  3. 三级封锁协议:在一级封锁协议的基础上,增加事务T在读取数据R前必须先对其加S锁,直到事务结束才释放

    进一步防止了不可重复读。保证了不发生读“脏”数据和不发生丢失修改以及不可重复读。

封锁协议级别越高,一致性程度越高

在这里插入图片描述

11.4 活锁和死锁

11.4.1 活锁

事务T2永远等待,这就是活锁的情形。

在这里插入图片描述

避免活锁的简单方法是采用先来先服务的策略。

11.4.2 死锁

1. 死锁的预防

  1. 一次封锁法:每个事务必须一次将所有要使用的数据全部加锁。
    缺点:降低了系统的并发度。而且数据是不断变化的,很难事先精确确定每个事务所要封锁的数据对象。

  2. 顺序封锁法:预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实现封锁。

缺点:封锁的数据对象极多且在不断变化。事务的封锁请求随着事务的执行而动态地决定,很难事先确定。

预防死锁的策略适合操作系统,不太适合数据库,更多使用诊断并解除死锁的方法

2.死锁的诊断与解除

  1. 超时法:实现简单,用得最多
    缺点:可能误判。若时限太长不能及时发现
  2. 等待图法:精确判断死锁

在这里插入图片描述

解除死锁的方法:选择一个处理死锁代价最小的事务,将其撤销,释放此事务持有的所有的锁,使其他事务得以继续运行下去。但实际上是很难的,通常随便选定一个回滚,因为代价很难判断。

11.5 并发调度的可串行性

11.5.1 可串行化调度

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

可串行性(serializability)是并发事务正确调度的准则

11.5.2 冲突可串行化调度

冲突操作:不同的事务对同一个数据的读写操作和写写操作

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

一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度Sc’,如果Sc’是串行的,调度Sc为冲突可串行化的调度。若一个调度是冲突可串行化,则一定是可串行化的调度。(充分不必要条件)

在实际系统中,通常用优先图。一个事务对应一个节点,两个事务间有有向边(Ti->Tj)当且仅当Ti在Tj前执行,意味着他们之间有冲突不能交换。图没有环意味着冲突可串行化。

11.6 两段锁协议

定义:所有事务必须分两个阶段对数据项进行加锁和解锁

所谓两端锁协议是指所有的事务必须分为两个阶段对数据项进行加锁和解锁:

  • 在对任何数据进行读写操作之前,首先要申请并获得对该数据的封锁
  • 在释放一个封锁之后,事务不再申请和获得任何其他封锁

事务分为两个阶段:

  1. 获得封锁,也称为扩展阶段,可以申请获得任何数据项上的任何类型的锁,不能释放任何锁
  2. 释放封锁,也称为收缩阶段,可以释放任何锁,但是不能申请任何锁

可以证明,若并发执行的所有事务均遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的(充分不必要条件),但是可能导致死锁

11.7 封锁的粒度

封锁粒度:封锁对象的大小,包括逻辑单元(属性值、关系……)和物理单元(页、物理记录……)

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

  • 粒度大,开销小,并发度小
  • 粒度小,开销大,并发度大

11.7.1 多粒度封锁

多粒度树:根是整个数据库,表示最大的数据粒度,叶节点表示最小的数据粒度

多粒度封锁协议:对一个结点加锁意味着这个结点的所有后代结点也被加以相同类型的锁

在这里插入图片描述

  • 显式封锁:应事务的要求直接加到数据对象上的锁
  • 隐式封锁:该数据对象没有被独立加锁,是由于其上级结点加锁而使该数据对象加上了锁

加锁过程:对R1加X锁,需要搜索其上级结点数据库、R1本身和R1的下级结点,如果其中某一个数据对象已经加了不相容锁,则必须等待。开销太大,解决方法是意向锁

11.7.2 意向锁

意向锁:如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;对任一结点加锁时,必须先对它的上层加意向锁

意向锁:

  1. 意向共享锁(IS锁):表示它的后代结点拟加X锁
  2. 意向排他锁(IX锁)
  3. 共享意向排他锁(SIX锁):对它加S锁,再加IX锁

在这里插入图片描述

加锁方法:从根开始对它的上层结点加意向锁,再对数据对象加锁。释放封锁则自下而上地进行

优点:提高了系统的并发度,减少了加锁和解锁的开销。

猜你喜欢

转载自blog.csdn.net/qq_21125183/article/details/84842682