11 Transactions¶
说明
本文档仅涉及部分内容,仅可用于复习重点知识
1 Transaction Concept¶
对于一个 DBMS,需要解决两个主要问题:
- 多用户或多程序的 concurrent executions
- 各种 failures,比如硬件损坏,系统崩溃
transaction 的定义:事务是数据库操作的基本单位,包含一组逻辑相关的 SQL 语句(如查询、插入、修改等),这些语句要么全部成功执行(提交),要么全部不执行(回滚)
transaction 的目的:
- 并发控制:确保多个事务同时执行时,数据库仍能保持正确性和一致性
- 数据完整性:通过提交或回滚机制,防止部分操作导致数据不一致(例如转账操作中,一方扣款而另一方未收款)
ACID Properties:
- Atomicity(原子性):事务的所有操作要么全部完成,要么全部不完成
- Consistency(一致性):事务执行前后,数据库必须满足预定义的规则(如约束、触发器等)。这意味着事务只能将数据库从一个有效状态转换到另一个有效状态,不允许违反任何预定义的规则或约束
- Isolation(隔离性):并发事务之间互不干扰,中间状态对其他事务不可见
- Durability(持久性):事务提交后,其结果永久保存在数据库中,即使发生系统故障也不会丢失已提交的更新
2 Transaction State¶
- Active(活跃):事务正在执行 SQL 语句(如读写数据)
- Partially Committed(部分提交):所有操作已执行,但数据可能仍在内存缓冲区,尚未写入磁盘。此时若系统崩溃,事务可能丢失
- Failed(失败):因错误(如违反约束、死锁)无法继续执行
- Aborted(中止):回滚所有操作,数据库恢复原状。用户可选择重启事务(如因临时死锁)或终止(如逻辑错误)
- Committed(提交):数据持久化到磁盘,事务成功结束

3 Implementation of Atomicity and Durability¶
数据库系统的 recovery-management component(恢复管理组件)负责实现原子性(Atomicity)和持久性(Durability)的支持
影子数据库方案(Shadow-Database Scheme):一种简单但低效的方案:
- 初始状态:
db_pointer
指向一个一致的数据库副本(影子副本) - 事务执行:修改操作在新副本上进行,影子副本保持不变
-
事务提交:
- 将新副本数据强制写入磁盘(确保持久性)
- 通过原子性地切换
db_pointer
指向新副本,实现原子性(若切换失败,仍保留原副本)
-
事务中止:直接丢弃新副本,无需恢复(影子副本始终完好)
4 Concurrent Executions¶
优势:
- 提高处理器和磁盘利用率,从而提升事务吞吐量(Throughput):一个事务使用 CPU 时,另一个事务可以同时读写磁盘
- 减少事务的平均响应时间:短事务无需等待长事务完成
问题:尽管每个事务本身是正确的,但并发操作可能破坏数据一致性
Concurrency Control Schemes(并发控制机制):
- 通过隔离机制控制并发事务的交互,防止它们破坏数据库的一致性
- 实现 Serializability(可串行化),Recoverability(可恢复性)
Schedule(调度):多个并发事务的指令(如读、写、提交等)按时间顺序排列的执行序列
- 完整性:必须包含所有相关事务的全部指令,不能遗漏
- 顺序保留:每个事务内部的指令顺序必须与原始定义一致


5 Serializability¶
可串行化是并发控制的黄金标准,确保并发执行的事务最终结果与某种串行顺序执行的结果一致,从而维持数据一致性
- Conflict Serializability(冲突可串行化):通过交换非冲突操作(如两个事务读取同一数据)得到的等价串行调度
- View Serializability(视图可串行化):要求并发调度的“读-写”依赖关系与某个串行调度完全一致
假设:
- 忽略读写之外的操作:我们仅关注事务的读(read)和写(write)指令,其他操作(如计算、条件判断等)被忽略
- 允许本地缓冲区的任意计算:假设事务在两次读写之间可以对本地缓冲区(local buffers)中的数据进行任意计算处理
- 简化的调度仅包含读写指令:我们所研究的简化调度序列仅由读和写操作构成
5.1 Conflict Serializability¶
事务 Ti 的指令 li 和事务 Tj 的指令 lj 冲突,当且仅当:
- 两者访问同一数据项 Q
- 至少有一个指令是写操作
就像 RAW、WAR、WAW 一样
Conflict Equivalent(冲突等价):如果一个调度 S 可以通过一系列非冲突指令的交换转换成调度 S',则称 S 和 S' 是冲突等价
conflict serializable(冲突可串行化):如果一个调度 S 与某个串行调度冲突等价


* 5.2 View Serializability¶
view equivalent 需要满足三个条件:
- 首读条件:要求两个调度中,读取初始值的事务必须一致。即如果一个事务在第一个调度中读取了某个数据的初始值,在第二个调度中也必须如此
- 写读条件:要求读操作的数据来源必须一致。即如果一个事务读取了另一个事务写入的值,那么在另一个调度中,这个读操作也必须读取同一个事务的同一个写操作产生的值
- 末写条件:要求两个调度中,最后写入每个数据项的事务必须相同
一个 schedule S 是 view serializable 如果它和另外一个 serial schedule 是 view equivalent
一个 conflict serializable schedule 一定是 view serializable,反之不一定

所有 view serializable schedule 但不是 conflict serializable 都有 blind writes(盲写)
盲写:事务写入一个数据项而没有先读取它(即“盲目”修改数据)
6 Recoverability¶
6.1 Recoverable Schedules¶
Recoverable Schedules(可恢复调度):一个调度是可恢复的,如果满足:若事务 T1 读取了 T2 写入的数据,则 T1 必须在 T2 之前提交
这是为了防止级联回滚(Cascading Rollback),即一个事务的回滚导致其他事务也需回滚

6.2 Cascading Rollbacks¶
级联回滚:指一个事务的失败引发其他依赖它的事务连锁回滚的现象

6.3 Cascadeless Schedules¶
级联无关调度:不会发生 cascading rollbacks 的调度
每个级联无关调度都同时是可恢复调度
理想情况下应将所有调度限制为级联无关调度
这就是避免上述问题产生的方法,我们很难解决问题,那我们就防止这些问题发生
7 Implementation of Isolation¶
- 串行执行策略:每次只允许一个事务执行的策略可以生成串行调度,但并发度非常低
- 为了保持数据库一致性,调度必须是冲突可串行化或视图可串行化的,且必须是可恢复的,最好还是级联无关的
- 并发控制方案需要在允许的并发量和产生的开销之间进行权衡
- 有些方案只允许生成冲突可串行化的调度,而其他方案则允许生成非冲突可串行化的视图可串行化调度
8 Transaction Definition in SQL¶
事务的基本特性
- 隐式开始:SQL 中不需要显式声明"开始事务"
- 显式结束:必须通过
COMMIT
或ROLLBACK
明确结束事务
在几乎所有数据库系统中,默认情况下,每个 SQL 语句在执行成功后也会隐式提交。可以通过数据库指令关闭隐式提交
9 Testing for Serializability¶
precedence graph(前驱图):一个有向图,其中顶点是事务
如果两个事务发生冲突,并且 Tᵢ 比 Tⱼ 更早访问引发冲突的数据项,我们就从 Tᵢ 到 Tⱼ 画一条弧,可以用访问的数据项标记这条弧

9.1 Test for Conflict Serializability¶
一个调度是冲突可串行化的,当且仅当其前驱图是无环的(acyclic)
如果前驱图无环,可以通过图的拓扑排序(topological sorting)获得可串行化顺序

* 9.2 Test for View Serializability¶
用于检测 conflict serializability 的 precedence graph 不能直接用于检测 view serializability
检测一个 schedule 是否是 view serializability 的问题是一个 NP-complete 问题
9.3 Concurrency Control vs. Serializability Tests¶
- 并发控制协议允许并发调度,但确保调度是冲突/视图可串行化的,并且是可恢复和级联无关的
- 并发控制协议通常不会在构建过程中检查前驱图,相反,协议通过制定规则来避免不可串行化的调度
- 不同的并发控制协议在允许的并发量和产生的开销之间提供不同的权衡
- 可串行化测试帮助我们理解为什么某个并发控制协议是正确的