一、为什么要进行并发控制
1.1 三种典型的不一致现象
1.2 并发控制的缘由
1.3 并发控制及相应的事务处理技术是DBMS的核心技术
二、什么是事务
2.1 事务的概念
- 事务:事务是数据库管理系统提供的控制数据操作的一种手段,通过这一手段,应用程序员将一系列的数据库操作组合在一起作为一个整体进行操作和控制,以便数据库管理系统能够提供一致性状态转换的保证。
2.2 事务的宏观性和微观性
2.2.1 事务的宏观性
- 一个存取或改变数据库内容的程序一次执行,或者说一条或多条SQL语句的一次执行被看作一个事务。
- 事务一般是由应用程序员提出,因此有开始和结束,结束前需要提交或撤销
- 在嵌入式SQL程序中,任何一条数据库操纵语句都会引发一个新事务的开始,只要该程序当前没有正在处理的事务。而事务的结束是需要应用程序员通过commit或rollback确认的。
- 一段程序语句,可以会循环执行。执行中,由SQL语句引出事务,至Commit/RollBack结束事务,每次重复执行都将产生一个事务
2.2.2 事务的微观性
- 事务的微观性:对数据库的一系列基本操作(读、写)的一个整体性执行
- 事务的并发执行:多个事务从宏观角度上看是并行执行的,但其微观上的基本操作(读,写)则可以是交叉执行的。
2.3 事务的特性
2.3.1 ACID
- 原子性(Atomicity):DBMS能够保证事务的一组更新操作是原子不可分的,即对DB而言,要么全做,要么全不做
- 一致性(Consisitency):DBMS保证事务的操作状态是正确的,符合一致性的操作规则,不能出现三种典型的不一致性。它是进一步由隔离性来保证的
- 隔离性(Isolation):DBMS保证并发执行的多个事务之间互相不受影响。例如两个事务T1和T2,即使并发执行,也相当于或先执行了T1,再执行T2;或者先执行了T2,再执行T1
- 持久性(Durability):DBMS保证已提交事务影响是持久的,被撤销的事务的影响是可恢复的
- 换句话说:具有ACID特性的若干数据库基本操作的组合体被称为事务
2.4 DBMS对事务的控制
三、事务调度与可串行性
3.1 基本概念
- 事务调度:一组事务的基本步(读、写、其他控制操作如加锁、解锁等)的一种执行顺序称为对这组事务的一个调度
- 并发(并行)调度:多个事务从宏观上看是并行执行的,但其微观上的基本操作(读、写)则是交叉执行的
- 并发调度的正确性:当且仅当在这个并发调度下所得到的新数据库结果与分别串行地运行这些事务所得到的新数据库完全一致,则说调度是正确的
- 可串行性:如果不管数据库初始状态如何,一个调度对数据库状态的影响都和某个串行调度相同,则我们说这个调度是可串行化的或具有可串行性
3.2 冲突可串行
- 冲突:调度中一对连续的动作,它们满足:如果它们的顺序交换,那么涉及的事务中至少有一个事务的行为会改变。
- 有冲突的两个操作是不能交换次序的,没有冲突的两个事务是可交换的
- 几种冲突的情况:
- 同一事务的任何两个操作都是冲突的
- 不同事务对同一元素的两个写操作是冲突的
- 不同事务对同一元素的两个写操作是冲突的
- 不同事务对同一元素的一读一写操作是冲突的
- 冲突可串行性:一个调度,如果通过交换相邻两个无冲突的操作能够转换到某一个串行的调度,则称此调度为冲突可串行化的调度
- 冲突可串行性是比可串行性要严格的概念
- 满足冲突可串行性,一定满足可串行性;反之不然
3.3 冲突可串行性判别算法
- 构造一个前驱图(有向图)
- 结点是每一个事务(
)。如果
的一个操作与
的一个操作发生冲突,且
在
前执行,则绘制一条边,由
指向
,表征
要在
前执行。
- 测试检测:如果此有向图没有环,则是冲突可串行化的。
四、基于封锁的并发控制方法
4.1 什么是锁
- “锁”是控制并发的一种手段
- 每一数据元素都有唯一的锁
- 每一事务读写数据元素前,都要获得锁
- 如果被其他事务持有该元素的锁,则要等待
- 事务处理完成后要释放锁
- 调度器可利用锁来保证冲突可串行性
- 锁本身并不能保证冲突可串行性,但是锁为调度提供了控制的手段,如何用锁,需要用不同的协议来实现
4.2 封锁协议需要考虑什么
4.2.1 锁的类型
- 排他锁X:只有一个事务能读、写,其他任何事务都不能读、写
- 共享锁S:所有事务都可以读,但任何事务都不能写
- 更新锁U:初始读,以后可升级为写
- 增量锁I:增量更新,区分增量更新和其他类型的更新
4.2.2 相容性矩阵
- 当某事务对一数据对象持有一种锁时,另一种事务再申请对该对象某一类型的锁,是允许还是不允许
4.2.3 加锁/解锁时机
- 0级协议(0-LP)
- 有写要求的数据对象A加排他锁,不再访问后即刻解锁。可防止丢失修改,但允许脏读,允许重复读错误。
- 1级协议(1-LP)
- 有写要求的数据对象A加排他锁,事务提交时刻解锁。可防止丢失修改,可恢复,防止脏读,允许重复读错误。
- 2级协议(2-LP)
- 有写要求的数据对象A加排他锁,事务提交时刻解锁。有读要求的数据对象B加共享锁,不再访问后立即解锁。可防止丢失修改,防止脏读,不允许重复读错误。
- 3级协议(3-LP)
- 有写要求的数据对象A加排他锁,事务提交时刻解锁。有读要求的数据对象B加共享锁,事务提交时刻解锁。防止所有不一致性。
4.2.4 隔离性级别
- 读未提交(相当于0级协议)
- 读已提交(相当于1级协议)
- 可重复读(相当于2级协议)
- 可串行化(相当于3级协议)
- 幻读:指的事务不是串行发生时的一种现象,是事务A读取了事务B已提交的新增数据。
4.2.5 封锁粒度
- 封锁粒度是指封锁数据对象的大小
- 粒度单位:属性值
元组
元组集合
整个关系
整个DB
某索引项
整个索引
- 由前往后:并发度小,封锁开销小;
- 由后往前:并发度大,封锁开销也大;
4.3 两段锁协议
- 一种基于锁的并发控制方法
- 两段锁协议是可以保证冲突可串行性的
- 可能会产生死锁
4.3.1 概念
- 读写数据之前要获得锁。每个事务中所有封锁请求先于任何一个解锁请求
- 两个阶段:加锁段,解锁段。加锁段中不能有解锁操作,解锁段中不能有加锁操作
4.4 并发控制方法
- 基于锁的并发控制方法:两段锁协议
- 基于时间戳的并发控制方法:借助于时间戳,强制使一组并发事务的交叉执行,等价于一个特定顺序的串行执行
- 基于有效性确认的并发控制方法:事务在启动的时刻被赋予唯一的时间戳,以示其启动顺序,为每一活跃事务保存其读写数据的集合,通过对多个事务的读写集合,判断是否有冲突,来完成事务的提交与回滚,强制事务以可串行化的方式执行。