第十一章 并发控制
等待 等待
获得XlockA 读A=15 AA-1
③读A=50 读B=100 和=150 Commit Ulock A Ulock B ④
⑤
写回A=14 Commit Ulock A
⑤
Xlock B 等待 等待 等待 等待 等待 等待 等待 等待 获得Xlock B 读B=100 BB*2 写回B=200 Commit Ulock B
一次封锁法可有效地防止死锁发生,但也存在问题: 其一,一次就将以后要用到的数据全部加锁,势必扩大了 封锁的范围,从而降低系统的并发度。 其二,数据库中的数据是不断变化的,原来不要求封锁的 数据在执行过程中可能会变成封锁对象,所以很难事先精 确地确定每个事务所要封锁的数据对象,为此只能扩大封 锁范围,将事务在执行过程中可能要封锁的数据对象全部 加锁。
11.4 活锁和死锁 DBMS的并发控制子系统一旦检测到系统中存 在死锁,就要设法解除。通常采用的方法是选 择一个处理死锁代价最小的事务,将其撤销, 释放此事物持有的所有的锁,使其它事务得以 继续运行下去。当然,对撤销的事务所执行的 数据修改必须加以恢复。
11.2 封锁(Locking)
排它锁又称写锁。若事务T对数据对象加上X锁,则只 允许T读取和修改A,其他任何事务都不能再对A加任 何类型的锁,直到T释放A上的锁。这就保证了其他事 务在T释放A上的锁之前不能再读取和修改A。 共享锁又称读锁。若事务T对数据对象加上S锁,则事 务T可以读A但不能修改A,其他事务只能对A加S锁, 而不能加X锁,直到T释放A上的锁。这就保证了其他 事务可以读A,但在T释放A上的S锁之前不能修改A。
11.1 并发控制概述
3. 读“脏”数据(Dirty Read) 读“脏”数据是指事务T1修改某一数据,并将其写回 磁盘,事务T2读取同一数据后,T1由于某种原因被撤 销,这时T1修改过的数据恢复原值,T2读到的数据就 与数据库中的数据不一致,则T2读到的数据就为“脏” 数据。 产生此类数据不一致的主要原因是并发操作破坏了事 物的隔离性。并发控制就是要用正确的方式调度并发 操作,使一个用户事务不受其他用户的干扰,从而避 免造成数据的不一致性。 并发控制的主要技术就是封锁(Locking)。
Lock R
等待 Lock R Lock R 等待 等待 Unlock 等待 Lock R
等待
等待 等待 等待 等待
等待
等待
(a)活锁
(b)死锁
活锁和死锁
11.4 活锁和死锁 二、死锁
如果事务T1封锁了数据R1,T2封锁了数据R2,然后 T1又请求封锁R2,因T2已经封锁了R2,于是T1等待 T2释放R2上的锁。接着T2又请求封锁R1,因T1已经 封锁了R1,T2也只能等待T1释放R1上的锁。这样就 出现了T1在等待T2,而T2又在等待T1的局面,T1和 T2两个事务永远不能结束,形成死锁。
11.3 封锁协议
二、二级封锁协议 二级封锁协议是:一级封锁协议加上事务T在读取数 据R之前必须先对其加S锁,直到读完后即可释放S锁。 二级封锁协议除防止丢失修改,还可以进一步防止读 “赃”数据。
三、三级封锁协议
三级封锁协议是:一级封锁协议加上事务T在读取数据 R之前必须先对其加S锁,直到事务结束才释放。 三级封锁协议除防止丢失修改和不读“赃”数据外, 还可以进一步防止不可重复读。
11.4 活锁和死锁
死锁的解决办法主要有两类。 1.死锁的防御 1) 一次封锁法 要求每个事物必须一次将所有要使用的数据全 部加锁,否则就不能继续进行。 例如:如果事务T1将数据对象R1和R2一次加锁,T1就可 以执行下去,而T2等待。T1执行完后释放R1,R2上的锁, T2继续进行。这样就不会发生死锁。
11.4 活锁和死锁
2.死锁的诊断与解除 1) 超时法 如果事务的等待时间超过了规定的时限,就认 为发生了死锁。 超时法实现简单,但其不足也很明显。其一,有可能 误判死锁,事务因为其它原因使等待时间超过时限, 系统会误认为发生了死锁。其二,时限若设臵得太长, 死锁发生后不能及时发现。 2) 等待图法 事务等待图是一个有向图 G=(T,U)。T为结 点集合,每个结点表示正运行的事务;U为边的集合, 每条边表示事务等待的情况。若T1等待T2,则T1, T2之间划一条有向边,从T1指向T2。事务等待图动 态地反映了所有事务的等待情况。并发控制子系统周 期性地(比如每隔1秒)检测事务等待图,如果发现 图中存在回路,则表示系统中出现了死锁。
第十一章 并发控制
并发控制概述
封锁(Locking)
封锁协议 活锁和死锁 并发调度的可串行性 两段锁协议
封锁的粒度
小结
数据库是一个共享资源,可以供多个用户使用允许多个 用户同时使用的数据库系统称为多用户系统。例如飞机 订票系统、银行数据库系统等都是多用户数据库系统。 在这样的系统中,在同一时刻并行运行的事务数可达数 百个。 事务可以一个一个串行执行,即每个时刻只有一个事务 运行,其他事务必须等到这个事务结束以后方能运行。 事务在执行过程中需要不同的资源,有时需要CPU,有 时需要存取数据库,有时需要I/O,有时需要通信。如果 事务串行执行,则许多系统资源将处于空闲状态。因此, 为了充分利用系统资源,发挥数据库共享资源的特点, 应该允许多个事务并行地执行。
③ROLLBACK C恢复为100 Ulock C ④
读C=200
⑤ Commit Ulock C
(A)没有丢失修改
(B)可重复读
(C )不读“脏”数 据
用封锁机制解决三种数据不一致
8.3 封锁协议
不同级别的封锁协议
操作结束 事务结束 释放 一级封锁协议 二级封锁协议 三级封锁协议 释放
X 锁
S锁
操作结束 事务结束 释放 释放 不丢失 修改
一致性保持
不读“脏 ” 数据 可重复 读
√
√
√
√
√
√
√ √
√ √ √
11.4 活锁和死锁
封锁的方法可能引起活锁和死锁 一、活锁
如果事务T1封锁了数据R,事务T2又请求封锁R,于 是T2等待。T3也请求封锁R,当T1释放R上的锁后系 统首先批准了T3的请求,T2仍然等待。然后T4又请求 封锁R,当T3释放R上的锁后系统又批准了T4的请 求…… T2有可能永远等待,这就是活锁。
在单机处理系统中,事务的并行执行实际上是这些并 行事务的并行操作轮流交叉运行。这种并行执行方式 称为交叉并发方式(Interleaved Concurrency)。
在多处理机系统中,每个处理机可以运行一个事务, 多个处理机可以同时运行多个事务,实现多个事务真 正的并行运行。这种并行执行方式称为同时并发方式 (Simultaneous Concurrency)。
当多个用户并发地存取数据库时就会产生多个事务同 时存取同一数据的情况。若对并发操作不加控制就可 能会存取和存储不正确的数据,破坏数据库的一致性。 所以数据库管理系统必须提供并发控制机制。并发控 制机制是衡量一个数据库管理系统性能的重要标志之 一。
11.1 并发控制概述
事务是并发控制的基本单位,保证事务ACID特性是事 务处理的重要任务,而事务ACID特性可能遭到破坏的 原因之一是多个事务对数据库并发操作造成的。为了保 证数据库的一致性,DBMS需要对并发操作进行正确调 度。这就是数据库管理系统中并发控制机制的责任。 一个最常见并发操作的例子是飞机订票系统中的订票操 作。例如在该系统中的一个活动序列: ①甲售票点(甲事务)读出某航班的机票余额A,设A= 16; ②乙售票点(乙事务)读出同一航班的机票余额A,也 为16;
11.4 活锁和死锁
2)顺序封锁法 预先对数据库对象规定一个封锁顺序,所有 事物都按这个顺序实行封锁。 例如在B树结构的索引中,可以规定封锁的顺序必须是从 根节点开始,然后是下一级的子女节点,逐级封锁。 顺序封锁法可有效地防止死锁发生,但也存在问题。 其一,数据库系统中封锁的对象极多,并且随数据的插入、 删除等操作而不断变化,要维护这样的资源的封锁顺序非 常困难,成本也很高。 其二,事务的封锁请求可以随着事物的执行而动态地决定, 很难事先确定每一个事务要封锁的对象,因此也很难按规 定的顺序去施加封锁。 因此在操作系统中广泛采用的预防死锁的策略并不很适合 数据库的特点,所以DBMS在解决死锁的问题上普遍采用 的是诊断并解除死锁的方法。
11.1 并发控制概述
③甲售票点卖出一张机票,修改余额AA-1,所以A为 15张,把A写回数据库;
④乙售票点也卖出一张机票,修改余额AA-1,所以A 为15张,把A写回数据库。
结果明明卖出两张机票,数据库中机票余额只减少1。 这种情况称为数据库的不一致。这种不一致是由并发 操作引起的。 并发操作带来的数据不一致性包括三类:丢失修改、 不可重复读和读“脏”数据。
②
读C=200
③ROLLBACK C恢复为100
④
和=250 (验算不对) (B)不可重复读 (C )读“脏”数据
11.1 并发控制概述
1.丢失数据(Lost Update)
两个事务T1和T2读入同一数据并修改,T2提交 的结果破坏了T1提交的结果,导致T1的修改被 丢失。
11.1 并发控制概述
T1
①Xlock A 获得 ②读A=16
T2
T1
①Slock A Slock B 读A=50 读B=100 和=150 ②
T2
T1
①Xlock C 读C=100 CC*2 写回C=200 ②
T2
Xlock A ③AA-1 写 回 A=15 Commit Ulock A ④ 等待 等待
Slock C 等待 等待 等待 等待 等待 获得Slock C11.1 并发控制概述
三种数据不一致性
T1 ①读A=16 读A=16 ② ③AA-1 写回A=15 AA-1 写回A=15 (A)丢失修改 ③读A=50 读B=200 T2 T1 ①读A=50 读B=100 ② 和=150 T2 T1 ①读C=100 CC*2 写回C T2