数据库 之并发控制浅知识(概念,无代码,无原理)--封锁、活锁死锁、读锁写锁、两段锁
本文内容源自《数据库系统概论》,文章内容是一些浅显的知识,不涉及实现,这里有一个相关实现的文章链接一、并发控制概述并发操作带来的数据不一致性1.丢失修改(Lost Update)2.不可重复读(Non-repeatable Read)3.读“脏”数据(Dirty Read)不可重复读是指事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取结果。包括三种情况:T1读完一次数...
本文内容源自《数据库系统概论》,文章内容是一些浅显的知识,不涉及实现,这里有一个相关实现的文章链接
一、并发控制概述
并发操作带来的数据不一致性
1.丢失修改(Lost Update)
2.不可重复读(Non-repeatable Read)
3.读“脏”数据(Dirty Read)
不可重复读是指事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取结果。包括三种情况:T1读完一次数据之后,T2对数据做了增加、删除、修改操作,T1再次以相同的方式读数据时,不能得到与上次相同的数据。
二、封锁类型
基本封锁类型:排他锁/X锁(写锁)、共享锁/S锁(读锁)
1.排他锁允许读取和修改数据,排斥
2.共享锁允许读取、不允许修改数据,允许其他事务在该数据上加共享锁、不允许加排他锁
3.相容:读锁和读锁相容,其他情况均不相容(两个事务之间)(同一个事务中,)
三、封锁协议(解决数据一致性问题)
一级封锁协议(只加写锁)
(1)修改数据:事务在对数据进行修改之前必须加写锁,事务结束释放,可防止丢失修改
(2)读取数据:事务只需要读取数据时,不加锁,所以它不能保证可重复读和不读“脏”数据(因为不加锁,无法保证数据不被其他事务修改)
二级封锁协议(只加读锁)
(1)事务在读取数据之前必须加读锁(不允许其他事务修改数据),事务结束释放,可以防止丢失修改和读“脏”数据
(2)不能保证可重复读,因为读完之后就释放锁了
三级封锁协议(加读锁和写锁)
(1)修改数据:事务在对数据进行修改之前必须加写锁,事务结束释放,可防止丢失修改
(2)读取数据:事务在对数据进行读取之前必须加读锁,事务结束释放,可防止读脏数据和不可重复读
四、活锁和死锁(封锁协议带来的问题以及解决)
活锁
1.问题描述
出现一个请求封锁的事务处于永久等待
2.避免活锁
先来先服务策略
死锁
1.问题描述
T1和T2两个事务永远不能结束,即循环等待
2.死锁预防:破环死锁产生的条件(不太适合数据库的特点
)
一次封锁法:要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行(降低并发度)(遵守两段锁协议)
顺序封锁法:预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁(难以实现)
3.死锁的诊断和解除(更普遍采用的方式)
(1)死锁诊断
超时法:一个事务的等待时间超过了规定的时限,就认为发生了死锁
等待图法:用事务等待图动态反映所有事务的等待情况(若T1等待T2,则T1,T2之间划一条有向边,从T1指向T2),如果发现图中存在回路,则表示系统中出现了死锁
(2)死锁解除
选择一个处理死锁代价最小的事务,将其撤消,释放此事务持有的所有的锁,使其它事务能继续运行下去
五、并发调度的可串行性
可串行化调度
串行调度和可串行化的调度,才认为是正确调度
1.可串行化(Serializable)调度
多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行这些事务时的结果相同
2.可串行性(Serializability)
是并发事务正确调度的准则;一个给定的并发调度,当且仅当它是可串行化的,才认为是正确调度
对于这句话的理解,可以通过下面三张图:
冲突可串行化调度
定义:一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度Sc’,如果Sc’是串行的,称调度Sc是冲突可串行化的调度
可用这种方法判断一个调度是否是冲突可串行化的(若一个调度是冲突可串行化,则一定是可串行化的调度)
1.冲突操作:是指不同的事务对同一数据的读写操作和写写操作(回顾:对数据添加写锁和读锁之后,在上锁期间不允许其他事务对此数据添加锁)
2.不能交换的动作:同一事务的两个操作、不同事务的冲突操作
可以通过下面几张图理解:
六、两段锁协议(实现并发调度可串行性)(可能发生死锁)
数据库管理系统普遍采用两段锁协议的方法实现并发调度的可串行性,从而保证调度的正确性
遵守两段锁协议的一定是一个可行化调度
1.两个阶段:加锁和解锁
加锁阶段(也称为扩展阶段)不能释放任何锁,可以申请满足申请条件的锁
解锁阶段(也称为收缩阶段)不能申请任何锁,只能释放锁
2.在释放一个封锁之后,事务不再申请和获得任何其他封锁
若并发事务都遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的
七、封锁的粒度
定义:封锁对象的大小
封锁对象:逻辑单元、物理单元
在关系数据库中,封锁对象:
- 逻辑单元::属性值、属性值的集合、元组、关系、索引项、整个索引、整个数据库等
- 物理单元:页(数据页或索引页)、物理记录等
封锁粒度
1.封锁的粒度越大,数据库所能够封锁的数据单元就越少,并发度就越小,系统开销也越小
2.封锁的粒度越小,并发度较高,但系统开销也就越大
粒度:数据库 > 关系 > 元组
举例理解:
若封锁粒度是数据页,事务T1需要修改元组L1,则T1必须对包含L1的整个数据页A加锁。如果T1对A加锁后事务T2要修改A中元组L2,则T2被迫等待,直到T1释放A
如果封锁粒度是元组,则T1和T2可以同时对L1和L2加锁,不需要互相等待,提高了系统的并行度
又如,事务T需要读取整个表,若封锁粒度是元组,T必须对表中的每一个元组加锁,开销极大
3.选择封锁粒度(同时考虑封锁开销和并发度两个因素, 适当选择封锁粒度)
需要处理多个关系的大量元组的用户事务:以数据库为封锁单位
需要处理大量元组的用户事务:以关系为封锁单元
只处理少量元组的用户事务:以元组为封锁单位
多粒度封锁
1.多粒度树
以树形结构来表示多级封锁粒度,根结点是整个数据库,表示最大的数据粒度,叶结点表示最小的数据粒度
三级粒度树:
2.多粒度封锁协议
- 允许多粒度树中的每个结点被独立地加锁
- 对一个结点加锁意味着这个结点的所有后裔结点也被加以同样类型的锁
- 在多粒度封锁中一个数据对象可能以两种方式封锁:显式封锁和隐式封锁。显式封锁:直接加到数据对象上的封锁;隐式封锁:是该数据对象没有独立加锁,是由于其上级结点加锁而使该数据对象加上了锁
3.在对多粒度树上的某个结点进行加锁时,需要进行封锁冲突检查,检查其该结点数据对象、上级、下级是否已经加了不相容的锁
意向锁
1.目的:提高对某个数据对象加锁时系统的检查效率
2.要求
如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁
对任一结点加基本锁,必须先对它的上层结点加意向锁
3.意向锁分类
意向共享锁(IS锁)
意向排它锁(IX锁)
共享意向排它锁(SIX锁)
给某数据对象加锁时,要给其上级加相应的意向锁
事务T1要对R1中某个元组加S锁,则要首先对关系R1和数据库加IS锁
事务T1要对R1中某个元组加X锁,则要首先对关系R1和数据库加IX锁
如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX = S + IX。对某个表加SIX锁,则表示该事务要读整个表(所以要对该表加S锁),同时会更新个别元组(所以要对该表加IX锁)
4.意向锁的相容矩阵
5.锁的强度
6.加锁和解锁顺序
加锁:自上而下
解锁:自下而上
八、其他并发控制机制
时间戳方法
乐观控制法
多版本并发控制
更多推荐
所有评论(0)