事务管理与 PPT 09 并发控制
9. 事务与并发控制:多个人同时改账本,数据库怎么不乱¶
这一章以 第十三章 事务管理.docx 和 第十四章 并发控制.docx 为主要讲解来源。PPT 把并发控制放在后半段;Word 笔记补齐了 ACID、异常、schedule、冲突可串行化、视图可串行化、可恢复调度、2PL、死锁、多粒度锁。
先抓住全章主线:
9.1 事务:数据库里“一件完整的事”¶
事务是访问并可能更新数据库的一段程序执行。
经典例子是转账:
这两步必须作为整体存在:
9.2 ACID:四个字母分别保护什么¶
| 字母 | 名称 | 人话 |
|---|---|---|
| A | Atomicity 原子性 | 要么全做,要么全不做 |
| C | Consistency 一致性 | 事务前后数据库满足业务规则 |
| I | Isolation 隔离性 | 并发事务互相看不到乱七八糟的中间结果 |
| D | Durability 持久性 | commit 后,崩溃也不能丢 |
并发控制主要保护:
恢复系统主要保护:
9.3 事务状态:失败后要回滚¶
常见状态:
active:事务正在执行。
partially committed:最后一条语句执行完,准备提交。
committed:提交成功,结果必须持久。
failed:执行中出错或提交失败。
aborted:回滚完成,事务影响被清掉。
考点不是画状态图,而是理解:
这就是后面日志恢复的任务。
9.4 并发异常:四种“不隔离”的表现¶
Lost update 丢失修改¶
两个事务都读同一个值,然后都写回。
T1 的修改被 T2 覆盖,好像从没发生过。
Dirty read 读脏数据¶
T2 读到的是一个后来被撤销的值。
Non-repeatable read 不可重复读¶
同一个事务里两次读同一行,结果不同。
问题是:T1 执行期间被别的事务影响了。
Phantom 幻影¶
同一个事务里两次执行同一个范围查询,行数变了。
区别:
9.5 隔离级别:越高越安全,越低越并发¶
从高到低:
| 隔离级别 | 允许什么问题 |
|---|---|
| Serializable | 四类问题都不允许 |
| Repeatable Read | 通常防 dirty read / lost update / non-repeatable read,但可能有 phantom |
| Read Committed | 只保证不读未提交数据;不可重复读和 phantom 可能发生 |
| Read Uncommitted | 连 dirty read 都可能允许 |
Word 笔记里的记忆:
考试如果问“哪个隔离级别防 phantom”,通常答:
9.6 Schedule:把多个事务的读写排成一条时间线¶
Schedule 是:
串行调度:
串行调度一定隔离,但太慢。
并发调度:
我们希望它虽然交错,但结果像某个串行顺序。
这就是可串行化:
9.7 冲突:不同事务、同一数据、至少一个写¶
两个操作冲突,必须同时满足:
所以:
冲突的本质:
9.8 冲突可串行化:画前驱图,看有没有环¶
做题模板:
1. 每个事务 Ti 画成一个点。
2. 从左到右扫描 schedule。
3. 找所有冲突操作对。
4. 如果 Ti 的冲突操作在 Tj 前面,画 Ti -> Tj。
5. 图有环:不是 conflict serializable。
6. 图无环:是 conflict serializable;拓扑序就是等价串行顺序。
例子:
冲突,并且 T1 在前:\(T_1 \to T_2\)。
如果又有:
冲突,并且 T2 在前:\(T_2 \to T_1\)。
两条边成环:\(T_1 \to T_2 \to T_1\),所以不可冲突串行化。
9.9 视图可串行化:比冲突可串行化更宽¶
Word 笔记补了 view serializability。它比 conflict serializability 宽,但考试通常不要求复杂判定。
一个 schedule 和某个 serial schedule 视图等价,需要满足三件事:
1. 读到初始值的事务相同。
2. 每次 read 读到的是同一个事务写出来的值,也就是 reads-from 关系相同。
3. 每个数据项最后由哪个事务写入相同,也就是 final write 相同。
结论:
如果考选择题:
9.10 可恢复调度:读了谁的脏值,就必须等谁先提交¶
Recoverable schedule 的规则:
为什么?
Cascading rollback 级联回滚:
Cascadeless schedule:
它能避免级联回滚。
考试排序:
9.11 S 锁和 X 锁:读共享,写独占¶
锁是悲观并发控制:
两种基本锁:
兼容矩阵:
| 已有锁 | 新申请 S | 新申请 X |
|---|---|---|
| S | 可以 | 不可以 |
| X | 不可以 | 不可以 |
人话:
9.12 2PL:先只加锁,再只放锁¶
Two-Phase Locking:
lock point:
重要结论:
但注意:
也就是说:
9.13 Basic / Strict / Rigorous 2PL¶
Basic 2PL:
Strict 2PL:
好处:
坏处:
Rigorous / Strong 2PL:
更保守,也更容易保证严格性。
9.14 锁转换:先读后写,不必一开始就 X 锁¶
有时事务先读,后来才决定写。
如果一开始就加 X 锁:
如果先放 S 锁再加 X 锁:
所以有锁升级:
带锁转换的 2PL:
9.15 死锁:等待图有环¶
典型死锁:
谁都不放,谁都继续不了。
等待图 wait-for graph:
如果等待图有环:
这张 Word 图保留,因为 lock table / wait-for graph 题靠图会更快。
处理死锁:
避免死锁的两种思路:
9.16 Tree protocol:不满足 2PL,也能保证冲突可串行化¶
Tree protocol 是基于图的协议。
规则:
性质:
为什么不会死锁?
9.17 多粒度锁:表上先打“意向标记”¶
有时锁一条记录,有时锁整张表。
粒度:
问题:
为了快速判断,引入意向锁:
人话:
常见规则:
SIX 为什么和 S 冲突?
9.18 并发控制 A4 规则¶
冲突:不同事务 + 同一数据 + 至少一个写。
前驱图:先发生的冲突操作所在事务 -> 后发生事务。
前驱图有环:不是 conflict serializable。
前驱图无环:是 conflict serializable,拓扑序为等价串行序。
Conflict serializable 一定 view serializable,反之不一定。
Recoverable:读了谁写的值,就等谁先 commit。
Cascadeless:只读已提交数据,避免级联回滚。
S 锁读,X 锁写;S/S 兼容,其他冲突。
2PL:先加锁后放锁;保证 conflict serializable,但不是必要条件。
Strict 2PL:X 锁持有到 commit/abort,防 dirty read。
等待图有环:死锁。
Tree protocol:非 2PL,但保证 conflict serializable 且无死锁。
多粒度:IS/IX/SIX 是父节点上的意向标记。
