10.1并发控制的必要性
-
DBMS必须提供并发控制机制
-
并发控制机制的任务
- 对并发操作进行正确调度
- 保证事务的隔离性
- 保证数据的一致性
-
并发操作带来的数据不一致性
-
丢失修改(多次修改破坏前一个修改的结果)
-
不可重复读(第二次读数据的时候该数据已经被修改)
-
读“脏”数据(读取了某个失效的数据)
-
10.2封锁
- 封锁是实现并发控制的一个非常重要的技术
- 基本封锁类型
- 排它锁(X锁):写锁
- 共享锁(S锁):读锁
三级封锁协议(保证数据的一致性)
-
共同点:事务T在修改数据R之前必须对其加X锁,直到事务结束才释放
-
区别:对读锁的释放时机的要求不一样
-
1级封锁协议:不对S锁有要求,预防丢失修改
-
2级封锁协议:读完数据就释放S锁,预防读脏数据
-
3级封锁协议:事务结束再释放S锁,预防不可重复读
-
活锁和死锁
-
活锁:有能解开的时候,只是在排队等待资源,可能排队的时间长(先来先服务的策略)
-
死锁:解不开
-
死锁的预防策略
- 一次封锁法(全部加锁)(扩大封锁范围,但是降低并发度)
- 顺序封锁法(确定封锁顺序,先给A加锁才能给B加锁)(维护成本高,难于实现)
-
死锁的诊断和解除
- 超时法(人为规定时间,超时就认定为死锁)
- 等待图法(周期性检测事务等待图,有回路说明有死锁)(T1等待T2,
T1->T2
)
两段锁协议(保证并发调度的正确性)
- 可串行化的调度:事务的并行结果是正确的,当且仅当其结果与某一顺序串行的结果相同
- 保证并发操作调度正确性的方法
- 两段锁协议、时间戳、乐观控制法
- 两段锁协议:在释放一个锁之后,事务不再获得其他任何封锁
- 事务分为两个阶段:扩展阶段(获得封锁)+收缩阶段(释放封锁)
- 事务遵守两段锁协议是可串行化调度的充分不必要条件
- 遵守第三级封锁协议必然遵守两段锁协议
10.3封锁的粒度
封锁的粒度 越大 , 系统被封锁的对象 越少,并发度 越低,系统开销 越小
选择封锁粒度的因素:系统开销和并发度(Balance)
- 需要处理多个关系的大量元组的用户事务:以数据库为封锁单元
- 需要处理大量元组的用户事务:以关系为封锁单元
- 只处理少量元组的用户事务:以元组为封锁单元
多粒度封锁
多粒度树,根节点是整个数据库,叶节点是最小的数据粒度
显示封锁和隐式封锁
隐式封锁:由于其上级结点加锁而使得该数据对象加上了锁
显示封锁和隐式封锁的效果是一样的
意向锁
锁的类型包含S,X,IX,IS,SIX
SIX
是共享意向排它锁,即共享锁+意向排它锁
意向锁的目的:提高某个数据对象加锁时系统的检查效率
- 对任一节点加基本锁,必须先对它的上层结点加意向锁
- 对一个结点加意向锁,说明该节点的下层节点正在被封锁