第9章 事务调度与并发控制
9.1事务与事务调度
9.1.1 事务的概念
- 事务是构成数据库应用中一个独立逻辑工作单元的操作的集合,也是访问并可能更新数据库中各种数据项的一个程序执行单元。数据库系统通过执行各种事务实现对数据库数据的操作,管理和执行事务是DBMS的基本功能。
9.1.2 事务的特性(ACID特性)
1、原子性(Atomicity)
一个事务对数据库的所有操作是一个不可分割的工作单元,这些操作要么全部执行,要么一个也不执行。
-
一致性(Consistency)
当一个事务独立执行时,其执行结果应维护数据库的一致性,即数据库不会因事务执行而受到破坏。数据库满足全部完整性约束,处于正确的状态;
-
隔离性(Isolation)
当多个事务并发执行时,系统应保证一个事务的执行结果不受其他事务的干扰,事务并发执行结果与这些事务串行执行时的结果是一样的;
-
持久性(Durability)
一个事务一旦成功完成全部操作,则它对数据库的所有更新就永久地反映在数据库中,即使以后数据库发生了故障;
9.1.3 事务调度
- 一个事务中各操作的执行顺序和执行时机一方面取决于事务自身内部逻辑,
- 另一方面也受DBMS中事务调度机制的控制。
- 当多个事务并发执行时,DBMS必须采用合适的并发调度机制合理安排各个事务执行顺序,以保证事务的ACID特性。
-
调度分为串行调度和并发调度
- 串行调度的特点是一个事务的所有操作都执行完后才开始执行另一事务,不存在事务操作的交叉执行;
-
并发调度是指,在每个事务保持自身操作顺序的前提下,不同事务操作的交叉执行,DBMS交叉执行来自多个事务的各个操作,以提高数据库系统的性能。
9.1.4 可串行化调度(对并行调度而言的)
事务的串行调度能够产生正确的结果,但执行效率低
可串行化调度
如果 并发调度S 等价于 某一定义在TS上的串行调度,那么称 该并发调度S 为 可串行化调度;
给定两个定义在 事务集TS 上的 调度S 和 S’,如果可以通过交换 S 中一系列 非冲突操作 的执行顺序, 将S转换为S’,则称S与S’是 冲突等价。
- (操作冲突:如果两个操作I1, I2至少有一个对同一个数据项Q进行write)P165
-
如果定义在 事务集TS 上的 并发调度S 冲突等价于 事务集TS 上的某个 串行调度S’,则称S是冲突可串行的。
- 在引入冲突可串行概念后,判断一个并发调度是否正确, 可以归结为判断该调度是否 冲突可串行 的。
by 未闻花名🌸vwhm.net
9.2 基于锁的并发控制技术
9.2.1 锁的概念
- 对数据库系统中每个可能被多个事务并发访问的数据项设置锁,锁代表了对该数据项的访问权限。
- 即事务T在访问数据项Q前须向DBMS申请获得设置在Q上的锁,如成功,则T获得对Q的访问权,
- T对Q操作完成后,释放所占用的锁,允许其他事务获得该锁并访问Q,在T释放设置在Q上的锁前,其他事务不能访问Q。
-
锁的类型有两种:
- 互斥锁(X锁):(Exclusive,写锁)若事务T获得Q上的X锁,则事务T可以对Q读と写,
- 其他事务不能再对Q进行任何操作,直到T释放Q上的X锁;
-
共享锁(S锁):(Shared,读锁)若T获得Q上的S锁,则T可以对Q进行读取操作,但不可以修改,
- 同时,允许其他事务再申请获得Q上的S锁,与T并行读取Q,
- 但在T释放Q上的S锁前,其他事务不能对Q做任何修改;
9.2.2 加锁协议
- 三级加锁协议:(保证数据一致性)
- 1级加锁协议要求事务T在修改数据项Q之前必须先对Q加X锁,直到事务结束才释放,事务结束包括正常结束和非正常结束,
- 但事务T如果对Q只读而不写,则不需对Q加锁;
-
2级加锁协议是在1级加锁协议基础上,要求T在读取Q前必须先对其加S锁,读完后立即释放S锁;
-
3级加锁协议是在1级加锁协议基础上,要求在读取Q前必须先对其加S锁,但需等到事务结束后才释放S锁。
9.2.3 两阶段锁协议(保证事务调度可串行性)
两阶段锁协议
两阶段锁(2PL)基本原理如下:
1. 每个事务的执行过程划分为两个阶段,加锁阶段和解锁阶段;
2. 在加锁阶段,事务可以申请获得任何数据项上的任何类型的锁,但是不允许释放任何锁;
3. 在解锁阶段,事务可以释放任何数据上的任何类型的锁,但是不能再申请任何的锁;
4. 每个事务开始执行后就进入加锁阶段
5. 当第一次释放锁后,即进入解锁阶段。
by 未闻花名🌸vwhm.net
9.2.4 锁粒度
- 施加X锁和S锁的数据项大小称为锁粒度。
- 锁粒度越大,系统中可以被锁的数据项(锁之后的其他)就越少,
- 事务的并发执行度也越低,但同时系统的开销也小,
- 相反,当锁粒度越小时,事务的并发度高,但系统开销也较大;
9.3 死锁(事务无法获得对需要访问的数据项的控制权)处理
9.3.1 死锁预防
- 一次加锁法
该方法要求每个事务在开始时必须将需要访问的数据项全部加锁,否则不能执行下去,也就是要求事务必须一次性地获得对需要访问的全部数据项的访问权;
一次加锁法的缺点是:
- 多个数据项(MM)会长期被一个事务(大叔)锁定独占,导致其他事务(大叔)无法及时访问这些数据项(MM),降低了系统的并发(开放)程度;
- 由于很难事先精确知道每个事务在执行过程中需要加锁的全部数据项,只能扩大加锁范围,将事务执行时可能访问的所有数据项全部加锁,进一步降低了系统的并发程度;
-
顺序加锁法
该方法对数据库中事务访问的所有数据项规定一个加锁顺序,每个事务在执行过程中必须按此顺序对所需数据加锁;
顺序加锁法的缺点:
- 数据库中需要加锁的数据项非常多,并且不断变化,维护这些数据项的加锁顺序很困难,代价非常大;
- 事务访问的数据项有时无法事先完全确定,有时很难要求事务按照固定的顺序对这些数据项进行加锁;
9.3.2 死锁检测与恢复
- 死锁检测
- 可以利用事务等待图进行死锁检测,数据库系统出现死锁当且仅当事务等待图中包含回路,那么可知回路中的所有事务就是处于死锁的事务;
- 数据库并发控制子系统动态地构造和维护事务等待图,并周期地检测等待图,如图中有回路,则说明系统中出现了死锁;
2、死锁恢复
- 当发现死锁存在时,系统可以通过死锁恢复机制将系统从死锁中解救出来,
- 通常是选取一个或几个死锁事务,撤消这些事务,释放其所拥有的锁,消除事务等待图中的回路,从而解决了系统死锁问题;
- 如何决定撤消哪个事务或哪些事务,有两个最基本的原则:
- 选择处于最多条回路交点处的事务;
- 选择具有最少撤消代价的事务。
9.4 活锁(权限问题)处理
如果一个事务(MM)在系统不存在死锁的情况下,却长期得不到DBMS的获批(临幸),处于长时间等待中的情况叫活锁(守活寡),
为了避免出现活锁(守活寡),DBMS可采用先来先服务的原则解决(生理需求)。