第11章 并发控制
了解
- 数据库并发控制技术的必要性
- 活锁与死锁的概念
掌握
- 并发操作可能产生数据不一致的情况,包括丢失修改、不可重复读、读“脏”数据等
- 封锁的类型及不同封锁类型(X锁、S锁)的性质和定义,相关的相容控制矩阵
- 封锁协议的概念
- 封锁粒度的概念,多粒度封锁方法,多粒度封锁协议的相容控制矩阵
- 封锁协议与数据一致性的关系,并发调度的可串行性概念
- 两段锁协议与可串行性的关系,两段锁协议与死锁的关系
知识点
- 在数据库中为什么要并发控制?并发控制技术能保证事务的哪些特性?
- 数据库是共享资源,通常有许多个事务同时在运行。当多个事务并发地存取数据库时就会产生同时读取和/或修改同一数据的情况。若对并发操作不加控制就可能会存取和存储不正确的数据,破坏数据库的一致性。所以数据库管理系统必须提供并发控制机制。
- 并发控制可以保证事务的【一致性】和【隔离性】
- 并发操作带来的数据不一致性包括三类
- 丢失修改(LostUpdate)
两个事务T1和T2读入同一数据并修改,T2提交的结果破坏了(覆盖了)T1提交的结果,导致T1的修改被丢失。 - 不可重复读(Non-RepeatableRead)
不可重复读是指事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取结果。不可重复读包括三种情况1.事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读改数据时,得到与前一次不同的值2.事务T1按一定条件从数据库中读取了某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录消失了3.事务T1按一条件从数据库中读取某些数据记录后,事务T2插入了一些记录,当T1再次按相同条件读取数据时,发现多了一些记录后两种不可重复读有时也称为幻影(phantom row)现象 - 读“脏”数据(DirtyRead)
读“脏”数据是指事务T1修改某一数据,并将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被撤销,这时T1已修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致,则T2读到的数据就为“脏”数据,即不正确的数据。
- 丢失修改(LostUpdate)
- 避免不一致性的方法和技术就是并发控制。常用的并发控制技术包括封锁技术、时间戳方法、乐观控制方法、多版本并发控制方法等
- 封锁就是事务T在对某个数据对象例如表、记录等操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不能更新此数据对象。
- 基本的封锁类型有两种: 排它锁(简称X锁) 和共享锁(简称S锁)。
- 排它锁又称为写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。这就保证了其他事务在T释放A上的锁之前不能再读取和修改A。
- 共享锁又称为读锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。
- DBMS在对数据进行读写操作之前首先对该数据执行封锁操作
- 活锁产生的原因:当一系列封锁不能按照其先后顺序执行时,就可能导致一些事务无限期等待某个封锁,从而导致活锁。
- 避免活锁的简单方法是采用先来先服务的策略。当多个事务请求封锁同一数据对象时,封锁子系统按请求封锁的先后次序对事务排队,数据对象上的锁一旦释放就批准申请队列中第一个事务获得锁。
- 在数据库中,产生死锁的原因是两个或多个事务都已封锁了一些数据对象,然后又都请求已被其他事务封锁的数据加锁,从而出现死等待。防止死锁的发生其实就是要破坏产生死锁的条件。预防死锁通常有两种方法:
-
- 一次封锁法
要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行。 - 顺序封锁法
预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。
- 一次封锁法
- 数据库系统一般采用允许死锁发生,DBMS检测到死锁后加以解除的方法。
- DBMS中诊断死锁的方法与操作系统类似,一般使用超时法或事务等待图法。
- 超时法:如果一个事务的等待时间超过了规定的时限,就认为发生了死锁。
- DBMS并发控制子系统检测到死锁后,就要设法解除。通常采用的方法是选择一个处理死锁代价最小的事务,将其撤消,释放此事务持有的所有锁,使其他事务得以继续运行下去。
- 可串行化的调度是正确的调度。
- 可串行化的调度的定义:多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行它们时的结果相同,我们称这种调度策略为可串行化的调度。
- 综合题
- 证明题
- 为什么要引进意向锁? 意向锁的含义是什么?
-
- 引进意向锁是为了提高封锁子系统的效率。
- 原因是:在多粒度封锁方法中,一个数据对象可能以两种方式加锁—显式封锁和隐式封锁。因此系统在对某一数据对象加锁时不仅要检查该数据对象上有无(显式和隐式)封锁与之冲突;还要检查其所有上级结点和所有下级结点,看申请的封锁是否与这些结点上的(显式和隐式)封锁冲突;显然,这样的检查方法效率很低。为此引进了意向锁。
- 意向锁的含义是:对任一结点加锁时,必须先对它的上层结点加意向锁。引进意向锁后,系统对某一数据对象加锁时不必逐个检查与下一级结点的封锁冲突了。
- 试述常用的意向锁:IS锁,IX锁,SIX锁,给出这些锁的相容矩阵。
- IS锁:如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁。例如,要对某个元组加S锁,则要首先对关系和数据库加IS锁
- IX锁:如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁。例如,要对某个元组加X锁,则要首先对关系和数据库加IX锁。
- SIX锁:如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX = S + IX。
- 相容矩阵
补充
-
- 试述两段锁协议的概念。
- 两段锁协议是指所有事务必须分两个阶段对数据项加锁和解锁。
- 在对任何数据进行读、写操作之前,首先要申请并获得对该数据的封锁;
- 在释放一个封锁之后,事务不再申请和获得任何其他封锁。
- “两段”的含义是,事务分为两个阶段:
- 第一阶段是获得封锁,也称为扩展阶段。在这阶段,事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁。
- 第二阶段是释放封锁,也称为收缩阶段。在这阶段,事务释放已经获得的锁,但是不能再申请任何锁。
- 两段锁协议是指所有事务必须分两个阶段对数据项加锁和解锁。
- 不同封锁协议与系统一致性级别的关系是什么?
- 不同的封锁协议对应不同的一致性级别。
- 一级封锁协议可防止丢失修改,并保证事务T是可恢复的。在一级封锁协议中,对读数据是不加S锁的,所以它不能保证可重复读和不读“脏”数据。
- 二级封锁协议除防止了丢失修改,还可进一步防止读“脏”数据。在二级封锁协议中,由于读完数据后立即释放S锁,所以它不能保证可重复读。
- 在三级封锁协议中,无论是读数据还是写数据都加长锁,即都要到事务结束时才释放封锁。所以三级封锁协议除防止了丢失修改和不读“脏”数据外,还进一步防止了不可重复读。
- 什么是封锁协议?不同级别的封锁协议的主要区别是什么?
- 在运用封锁技术对数据加锁时,要约定一些规则。例如,在运用X锁和S锁对数据对象加锁时,要约定何时申请X锁或S锁、何时释放封锁等。这些约定或者规则称为封锁协议(Locking Protocol)。对封锁方式约定不同的规则,就形成了各种不同的封锁协议。不同级别的封锁协议,例如《概论》中介绍的三级封锁协议,三级协议的主要区别在于什么操作需要申请封锁,何时申请封锁以及何时释放锁(即持锁时间的长短)。
- 一级封锁协议:事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。
- 二级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,读完后即可释放S锁。
- 三级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。
- 意向锁中为什么存在SIX锁,而没有XIS锁
- 完整性约束是否能够保证数据库在处理多个事务时处于一致状态
- 综合题
- 为了防止一个用户的工作不适当地影响另一个用户,应该采取【并发控制】
- 解决并发操作带来的数据不一致问题普遍采用【封锁】技术。
- 下列不属于并发操作带来的问题是【死锁】
- DBMS普遍采用【封锁】方法来保证调度的正确性
- 事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放,这是【一级封锁协议】
- 如果事务T获得了数据项Q上的排他锁,则T对Q【既可读又可写】
- 设事务T1和T2,对数据库中地数据A进行操作,可能有如下几种情况,请问哪一种不会发生冲突操作【T1正在读A,T2也要读A】
- 如果有两个事务,同时对数据库中同一数据进行操作,不会引起冲突的操作是【两个都是SELECT】
- 在数据库系统中,死锁属于【事务故障】
- 试述两段锁协议的概念。