并发控制
多用户数据库系统
允许多个用户同时使用的数据库系统
多事务执行方式
(1)事务串行执行
(2)交叉并发方式
(3)同时并发方式
11.1 并发控制概述
事务是并发控制的基本单位
并发控制机制的任务
对并发操作进行正确调度
保证事务的隔离性
保证数据库的一致性
并发操作带来的数据不一致性
1.丢失修改
2.不可重复读
3.读“脏”数据
数据不一致性:由于并发操作破坏了事务的隔离性
并发控制就是要用正确的方式调度并发操作,使一个用户事务的执行不受其他事务的干扰,从而避免造成数据的不一致性
并发控制的主要技术
封锁
时间戳
乐观控制法
多版本并发控制
11.2 封锁
基本封锁类型
排它锁(写锁)
共享锁(读锁)
11.3 封锁协议
封锁协议
在运用X锁和S锁对数据对象加锁时,需要约定一些规则,这些规则为封锁协议
三级封锁协议
1.一级封锁协议
事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。
可防止丢失修改,并保证事务T是可恢复的。
2.二级封锁协议
一级封锁协议加上事务T在读取数据R之前必须先对其 加S锁,读完后即可释放S锁。
二级封锁协议可以防止丢失修改和读“脏”数据
3.三级封锁协议
一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。
三级封锁协议可防止丢失修改、读脏数据和不可重复读。
| X锁 | S锁 | 一致性保证 | ||||
| 操作结束释放 | 事务结束释放 | 操作结束释放 | 事务结束释放 | 不丢失 修改 | 不读“脏”数据 | 可重复 读 |
一级封锁协议 |
| √ |
|
| √ |
|
|
二级封锁协议 |
| √ | √ |
| √ | √ |
|
三级封锁协议 |
| √ |
| √ | √ | √ | √ |
11.4 活锁和死锁
活锁:
事务T1封锁了数据R
事务T2又请求封锁R,于是T2等待。
T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待。
T4又请求封锁R,当T3释放了R上的封锁之后系统又批准了T4的请求……
T2有可能永远等待,这就是活锁的情形
避免活锁:采用先来先服务的策略
当多个事务请求封锁同一数据对象时
按请求封锁的先后次序对这些事务排队
该数据对象上的锁一旦释放,首先批准申请队列中第一个事务获得锁
死锁:
事务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)顺序封锁法
2. 死锁的诊断与解除
死锁的诊断
(1)超时法
如果一个事务的等待时间超过了规定的时限,就认为发生了死锁
(2)等待图法
用事务等待图动态反映所有事务的等待情况
3、解除死锁
选择一个处理死锁代价最小的事务,将其撤消
释放此事务持有的所有的锁,使其它事务能继续运行下去
11.5 并发调度的可串行性
数据库管理系统对并发事务不同的调度可能会产生不同的结果
串行调度是正确的
执行结果等价于串行调度的调度也是正确的,称为可串行化调度
可串行化调度
可串行化调度
多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行这些事务时的结果相同
可串行性 是并发事务正确调度的准则
一个给定的并发调度,当且仅当它是可串行化的,才认为是正确调度
冲突可串行化调度
冲突操作:是指不同的事务对同一数据的读写操
不能交换(Swap)的动作:
1、 同一事务的两个操作
2、不同事务的冲突操作
一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度Sc’,如果Sc’是串行的,称调度Sc是冲突可串行化的调度
11.6 两段锁协议
数据库管理系统普遍采用两段锁协议的方法实现并发调度的可串行性,从而保证调度的正确性
两段锁协议指所有事务必须分两个阶段对数据项加锁和解锁
事务分为两个阶段:
第一阶段是获得封锁,也称为扩展阶段
事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁
第二阶段是释放封锁,也称为收缩阶段
事务可以释放任何数据项上的任何类型的锁,但是不能再申请任何锁
若并发事务都遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的
遵守两段锁协议的事务可能发生死锁
11.7 封锁的粒度
封锁对象的大小称为封锁粒度
封锁的对象:逻辑单元,物理单元
封锁粒度与系统的并发度和并发控制的开销密切相关
1、封锁的粒度越大,数据库所能够封锁的数据单元就越少,并发度就越小,系统开销也越小;
2、封锁的粒度越小,并发度较高,但系统开销也就越大
多粒度封锁: 在一个系统中同时支持多种封锁粒度供不同的事务选择(考虑封锁开销和并发度)
多粒度树
以树形结构来表示多级封锁粒度
根结点是整个数据库,表示最大的数据粒度
叶结点表示最小的数据粒度
例如:三级粒度树。根结点为数据库,数据库的子结点为关系,关系的子结点为元组
1、允许多粒度树中的每个结点被独立地加锁
2、对一个结点加锁意味着这个结点的所有后裔结点也被加以同样类型的锁
3、在多粒度封锁中一个数据对象可能以两种方式封锁:显式封锁和隐式封锁
显式封锁: 直接加到数据对象上的封锁
隐式封锁:是该数据对象没有独立加锁,是由于其上级结点加锁而使该数据对象加上了锁
对某个数据对象加锁,系统要检查
1、该数据对象
2、有无显式封锁与之冲突
3.、所有上级结点
4、所有下级结点
意向锁
如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁
对任一结点加基本锁,必须先对它的上层结点加意向锁
意向共享 锁简称IS锁
如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁。
意向排它锁 简称IX锁
如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁。
共享意向排它锁 简称SIX锁
如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX = S + IX