1. Motivation (动机)
事务管理系统主要解决两个核心挑战:
处理故障 (Failures):
目标:保证原子性 (Atomicity)。
原理:无论硬件故障还是软件崩溃,如果事务执行失败,系统必须保证部分更新回滚,避免数据不一致。
并发执行 (Concurrent Executions):
目标:允许多个事务同时运行。
好处:
提高吞吐量 (Throughput):CPU 计算时,磁盘可以进行 I/O,资源利用率最大化。
减少响应时间 (Response Time):短事务不需要等待长事务执行完毕。
代价:必须严格控制(隔离性),否则会导致数据错乱。
2. Concepts (核心概念)
2.1 ACID 属性 (必背)
一个合法的事务必须满足 ACID:
A - Atomicity (原子性):“全有或全无”。操作要么全部成功,要么完全撤销。
C - Consistency (一致性):事务执行前后,数据库必须保持一致状态(如转账前后总金额不变)。
I - Isolation (隔离性):并发事务之间互不干扰,中间状态对外部不可见。
D - Durability (持久性):一旦提交 (Commit),修改必须永久保存,即使下一秒系统崩溃。
2.2 事务状态流转
正常流程:
Active(执行中)Partially Committed(语句执行完)Committed(写入磁盘/成功)。失败流程:
ActiveFailed(出错)Aborted(回滚)。
3. Concurrency Problems (三大并发病症)
理解这些“病症”是理解隔离级别的关键。
(1) 脏读 (Dirty Read) —— 读到了“假”数据
定义:读到了别的事务正在修改但尚未提交 (Uncommitted) 的数据。
后果:如果那个事务后来回滚了,你读到的数据就是从未存在过的。
场景:老板把你工资改成 1 万(未提交),你查到了 1 万。随后老板回滚,你空欢喜。
(2) 不可重复读 (Non-repeatable Read) —— 同一事务内,值变了
定义:在同一个事务内,两次读取同一行数据,结果不一样。
原因:在两次读取之间,别的事务 Update 或 Delete 了该数据并提交。
场景:会计第一次查工资 5000;老板修改为 8000 并提交;会计第二次查变成 8000。
(3) 幻读 (Phantom Read) —— 同一事务内,行数变了
定义:在同一个事务内,两次进行范围查询,结果集的行数不一样。
原因:在两次查询之间,别的事务 Insert 了符合条件的新行。
场景:老师统计及格人数 30 人;教务处插入一个新及格生;老师再统计变成 31 人。
★ 考试重点区分:
不可重复读:关注内容/值的改变 (Update)。
幻读:关注数量/行数的改变 (Insert/Delete)。
4. Isolation Levels (隔离级别)
SQL 定义的四种级别,就是为了解决上述病症的“药方”。
| 隔离级别 | 脏读? | 不可重复读? | 幻读? | 备注 |
|---|---|---|---|---|
| Read Uncommitted (未提交读) |
✅ 可能 | ✅ 可能 | ✅ 可能 | 裸奔模式。谁都能读未提交的数据,最不安全。 |
| Read Committed (已提交读) |
❌ 无 | ✅ 可能 | ✅ 可能 | Oracle/SQL Server 默认。我看不到你的草稿,只能看你发布(Commit)的内容。 |
| Repeatable Read (可重复读) |
❌ 无 | ❌ 无 | ✅ 可能 | MySQL 默认。我看书时,不允许别人拿笔改我这一页的字(但可以在空白处写新行)。 |
| Serializable (可串行化) |
❌ 无 | ❌ 无 | ❌ 无 | 最高封锁。串行执行,完全解决所有问题,但效率最低。 |
5. Method: 判定与计算 (解题工具箱)
5.1 冲突可串行化 (Conflict Serializability)
冲突定义:针对同一数据项,不同事务,且至少有一个是 Write。
vs 冲突 vs 冲突
优先图法 (Precedence Graph):
节点:每个事务
是一个节点。 画边:若
和 发生冲突,且操作顺序是 先 后,画边 。 判定:图无环 (Acyclic)
调度是冲突可串行化的。
5.2 调度属性判定 (Recoverable vs Cascadeless)
| 属性 | Recoverable (可恢复) | Cascadeless (无级联) |
|---|---|---|
| 核心关注 | Commit 的顺序 | Read 的时机 |
| 规则 | 如果 |
如果 |
| 通俗理解 | “读脏数据没关系,只要你别急着提交,等我提交并确认不会回滚了你再提交。” | “严禁读脏数据!必须等你提交了我才读。” |
| 关系 | 无级联调度 一定是 可恢复的。 | (反之不成立) |
6. Comprehensive Example (课后习题详解)
这是 Slide 32-33 的完整案例,涵盖了所有判定逻辑。
调度
: Write(Student 10) : Write(Grade 40) : Write(Student 30) : Read(Student 10) 冲突 A ( 读 写) : Commit : Commit : Read(Grade 40) 冲突 B ( 读 写) : Read(Student 30) 冲突 C ( 读 写) : Commit : Commit
题目解析
Q1: Construct the precedence graph (画出优先图)
分析冲突:
Conflict A (Student 10):
Write Read。边: Conflict B (Grade 40):
Write Read。边: Conflict C (Student 30):
Write Read。边:
结果图:
Q2: Is S a serializable schedule? (是可串行化吗?)
判定:检查优先图。
理由:图中不存在环 (No Cycle)。
答案:Yes。
(等价串行顺序:
或 )
Q3: Is S a recoverable schedule? (是可恢复吗?)
判定:检查冲突点 A (
读 ) 的提交顺序。 规则:被依赖者 (
) 必须先提交。 事实:
在第 5 步提交。 在第 6 步提交。 先提交了 违反规则。
答案:No。
(风险:若
在第6步回滚, 已经提交无法回滚,违反原子性)
Q4: Is S a cascadeless schedule? (是无级联吗?)
判定:检查冲突点 A (
读 ) 的读取时机。 规则:读取时,
必须已经提交。 事实:
在第 4 步读取时, 还是 Active 状态(未提交)。这是脏读。 答案:No。
7. Summary (解题速查表)
有环吗? 有
不可串行化;无 可串行化。 有“脏读”吗? (读了没提交的数据)
有
不是无级联。 无
是无级联 (且一定是可恢复)。
如果发生了脏读 (
读 ): 先提交 可恢复。 先提交 不可恢复 (致命错误)。
如果您喜欢我的文章,可以考虑打赏以支持我继续创作.