Appearance
ACID, Atomicity Consistency Isolation Durability
plain
┌─────────────┐
│ BEGIN │ ← 事务开始
└──────┬──────┘
↓
┌─────────────────────────────────────────┐
│ 执行SQL操作 │
│ ├── 检查约束 (Consistency) │
│ ├── 获取锁/创建版本 (Isolation) │
│ ├── 写入Undo Log (Atomicity) │
│ └── 写入Redo Log (Durability) │
└─────────────────────────────────────────┘
↓
┌────────────────────┐
│ COMMIT? │
└─────────┬──────────┘
↓
┌─────────────────────────────────┐
│ 是 → 刷Redo Log → 释放锁 → 成功 │
│ 否 → 读Undo Log → 回滚 → 失败 │
└────────────────────────────────┘| 数据库 | 原子性实现 | 隔离性实现 | 持久性策略 | 特色 |
|---|---|---|---|---|
| MySQL (InnoDB) | Undo Log | MVCC + 锁 | Redo Log + Double Write | 默认RR解决幻读 |
| PostgreSQL | WAL | MVCC (快照隔离) | WAL | 最严格的默认隔离 |
| Oracle | Undo表空间 | MVCC + 锁 | Redo Log | 商业级优化 |
| SQL Server | Transaction Log | 锁为主 | Write-Ahead Logging | 支持快照隔离 |
| SQLite | Journal/WAL | 数据库级锁 | WAL模式 | 嵌入式首选 |
| MVCC,Multi-Version Concurrency Control(多版本并发控制):读写不阻塞,提升并发性能。 |
原子性(Atomicity)
事务时一个不可分割的最小工作单元,事务中的所有操作要么全部成功提交,要么全部失败回滚。
plain
┌─────────────────────────────────────────┐
│ Transaction │
├─────────────────────────────────────────┤
│ BEGIN; │
│ OPR1: record Redo Log │
│ OPR2: MODIFY data page in memory │
│ OPR3: record Undo Log │
│ │
│ COMMIT; → flush Redo Log to disk │
│ ROLLBACK; → recovery from Undo Log │
└─────────────────────────────────────────┘组件:
- Undo Log (回滚日志):记录修改前的数据状态,用于事务回滚
- Redo Log (重做日志):记录修改后的数据状态,用于崩溃恢复
一致性(Consistency)
事务执行前后,数据库必须从一个有效状态转换到另一个有效状态,所有约束、规则、触发器都必须满足。
一致性是目的,原子性、隔离性、持久性是手段。
| 层面 | 说明 | 示例 |
|---|---|---|
| 数据库约束 | 主键、外键、唯一约束、CHECK约束 | 主键不能重复,外键必须存在 |
| 业务规则 | 应用程序定义的业务逻辑 | 账户余额不能为负数 |
| 数据完整性 | 数据间的逻辑关系正确 | 转账后总金额不变 |
plain
┌─────────────────────────────────────────┐
│ 一致性保障层次 │
├─────────────────────────────────────────┤
│ 应用层: 业务逻辑校验 │
│ ↓ │
│ SQL层: 约束检查 (PRIMARY KEY, FOREIGN KEY)│
│ ↓ │
│ 引擎层: 触发器 (TRIGGER) │
│ ↓ │
│ 存储层: 原子性+隔离性保障 │
└─────────────────────────────────────────┘隔离性(Isolation)
多事务并发时,事务单独执行,事务间不存在感知。
事务读取问题
| 事务读取问题 | 说明 |
|---|---|
| 脏读(Dirty Read) | 事务读取了另一个事务未提交的数据 |
| 不可重复读 (Non-repeatable Read) | 同事务内,多次读取同一数据结果不同 |
| 幻读 (Phantom Read) | 同事务内,多次读取同一范围数据数量不同 |
隔离级别(Isolation level)
隔离级别越高,并发性能越低。
| isolation level | 脏读(Dirty Read) | 不可重复读 (Non-repeatable Read) | 幻读 (Phantom Read) |
|---|---|---|---|
| READ UNCOMMITED | x | x | x |
| READ COMMITED | o | x | x |
| REPEATABLE READ | o | o | x |
| SERIALIZABLE | o | o | o |
数据库默认隔离级别
| 数据库 | 默认隔离级别 | 特点 |
|---|---|---|
| MySQL (InnoDB) | REPEATABLE READ | 通过MVCC+Next-Key Locking,实际上解决了幻读 |
| PostgreSQL | READ COMMITTED | 使用MVCC,提供较好的并发性能 |
| Oracle | READ COMMITTED | 使用Undo表空间实现多版本读 |
| SQL Server | READ COMMITTED | 支持快照隔离(Snapshot Isolation) |
| SQLite | SERIALIZABLE | 简单但并发性能较低 |
锁机制
| 锁类型 | 描述 | 使用场景 |
|---|---|---|
| 共享锁 (S锁) | 读锁,允许多个事务同时读 | SELECT ... LOCK IN SHARE MODE |
| 排他锁 (X锁) | 写锁,阻塞其他读写 | UPDATE, DELETE, INSERT |
| 意向锁 | 表级锁,表示事务将获取行锁 | 优化锁冲突检测 |
| 间隙锁 (Gap Lock) | 锁定索引记录之间的间隙 | REPEATABLE READ防幻读 |
| 临键锁 (Next-Key Lock) | 记录锁+间隙锁 | MySQL默认行锁算法 |
持久性(Durability)
一旦事务提交成功,对数据的修改就是永久性的,即使系统发生崩溃也不会丢失。
plain
┌─────────────────────────────────────────────────────────┐
│ 持久性保障体系 │
├─────────────────────────────────────────────────────────┤
│ │
│ 事务提交 │
│ ↓ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────┐ │
│ │ Redo Log │ → │ 磁盘文件 │ → │ 数据文件 │ │
│ │ (WAL机制) │ │ (ib_logfile)│ │ (.ibd) │ │
│ └─────────────┘ └─────────────┘ └─────────┘ │
│ ↑ ↓ ↑ │
│ 顺序写,性能高 崩溃恢复时回放 异步刷盘 │
│ │
│ 关键策略: Write-Ahead Logging (先写日志,再写磁盘) │
│ │
└────────────────────────────────────────────────────────┘崩溃恢复
plain
系统崩溃重启
↓
检查Redo Log
↓
┌──────────────────┐
│ 已提交但数据未刷盘? │ ──→ 重做(Redo) ──→ 数据恢复
│ 未提交但数据已刷盘? │ ──→ 回滚(Undo) ──→ 撤销修改
└──────────────────┘