一:事务运行方式
(1)概述
事务的运行方式主要分为串行和并行
- 串行:每个时刻只有一个事务运行
- 并行:同一时刻可以有多个事务同时运行
串行和并行的优缺点如下表,并行效率的确很高,但是会破坏事务的隔离性。因此要在保证一致性的前提下最大限度的提高并发度
不过需要注意的是,在操作系统中就说到过,单处理系统中,所谓的并行实际上是宏观上的并行运行,微观上的串行运行,也即 交叉并发
- 本章探讨的并发特指交叉并发
我们把允许多个用户同时使用同一个数据库的数据库系统称之为多用户数据库系统,在这种系统中,同一时刻并发运行的事务数量相当庞大。例如我们经常在使用的12306就是一个很典型的例子
(2)计算
两个事务\(S\)和\(T\),其中\(S\)有\(m\)条指令,\(T\)有\(n\)条指令,且每个事务内部指令的相对顺序不能错乱,那么可能的执行顺序有\(R\)种
(3)调度
调度:事务的一次执行顺序称之为一个调度,表示事务的指令在系统中执行的时间顺序、一组事务的调度必须保证
- 包含了所有事务的操作指令
- 一个事务中指令的顺序必须保持不变
(4)串行调度和并发调度
- 串行调度:属于同一事务的指令紧挨在一起执行,对于有\(n\)个事务的事务组,可以有\(n\)!个有效调度
- 并发调度:来自不同事务的指令可以交叉执行。并发调度有可能会导致错误结果,仅当并发调度等价于某个串行调度时,则称该并发调度时可串行化的、正确的
二:并发控制
(1)并发操作带来的数据不一致性问题
主要有三类数据不一致性问题
- 丢失修改
- 读脏数据
- 不可重复读
以如下飞机订票系统中的活动序列为例
①甲售票点(事务\(T_{1}\))读出某航班的机票余额A,设A=16
②乙售票点(事务\(T_{2}\))读出同一航班的机票余额A,也为16。
③甲售票点卖出一张机票,修改余额A←A-1,所以A为15,把A写回数据库。
④乙售票点也卖出一-张机票,修改余额A-A-1,所以A为15,把A写回数据库。
A:丢失修改
丢失修改:两个以上事务从数据库中读入同一数据并修改,其中后提交事务的提交结果破坏了先提交事务的提交结果,导致了先提交事务对数据库的修改丢失
在上面例子中,两个事务\(T_{1}\)和\(T_{2}\)读入同一数据并修改,但是\(T_{2}\)提交的结果破坏了\(T_{1}\)提交的结果,导致\(T_{1}\)的修改被丢失
B:读脏数据
读脏数据:事务1修改某一数据,并将其写回磁盘;事务2读取同一数据后,事务1由于某种原因被撤销,这时事务1已修改过的数据被恢复为原值,事务2读到的不稳定的瞬间数据就与数据库中的数据产生了不一致,是不正确的数据,又称为脏数据
例如\(T_{1}\)将C值修改为200,\(T_{2}\)读到C为200,此时\(T_{1}\)由于某种原因被撤销,因此C恢复为原值100,这时\(T_{2}\)读到的C为200,属于读脏
C:不可重复读
不可重复读:事物1读取数据后,事物2执行更新操作,使事物1无法再现前一次读取结果。共有三种情况
- 事物2修改了事物1所读数据,当事物1再次读该数据时,得到了与前一次不同的值
- 事务2删除了其中部分记录,当事务1再次按相同条件读取数据时,发现某些记录神秘地消失了
- 事务2插入了一些记录,当事务1再次按相同条件读取数据时,发现多了一些记录
(2)并发控制概念
并发控制:如果多个用户并发存取数据的行为不加以控制,那么极有可能破坏事务的隔离性和一致性。因此并发控制就是为了保证多用户并发操作数据库中信息时的正确性、一致性所采取的措施
(3)并发控制任务
- 对并发操作进行正确调度
- 保证事物的隔离性
- 保证数据库的一致性
(4)并发控制方法
- 加锁(Locking)
- 乐观假设(Optimistic)
- 时间戳(Timestamp)
- 多版本并发控制(MVCC)