Skip to content

ACID, Atomicity Consistency Isolation Durability

plain
                    ┌─────────────┐
                    │   BEGIN     │  ← 事务开始
                    └──────┬──────┘

    ┌─────────────────────────────────────────┐
    │  执行SQL操作                             │
    │  ├── 检查约束 (Consistency)              │
    │  ├── 获取锁/创建版本 (Isolation)         │
    │  ├── 写入Undo Log (Atomicity)           │
    │  └── 写入Redo Log (Durability)          │
    └─────────────────────────────────────────┘

              ┌────────────────────┐
              │     COMMIT?        │
              └─────────┬──────────┘

           ┌─────────────────────────────────┐
           │  是 → 刷Redo Log → 释放锁 → 成功  │
           │  否 → 读Undo Log → 回滚 → 失败   │
           └────────────────────────────────┘
数据库原子性实现隔离性实现持久性策略特色
MySQL (InnoDB)Undo LogMVCC + 锁Redo Log + Double Write默认RR解决幻读
PostgreSQLWALMVCC (快照隔离)WAL最严格的默认隔离
OracleUndo表空间MVCC + 锁Redo Log商业级优化
SQL ServerTransaction Log锁为主Write-Ahead Logging支持快照隔离
SQLiteJournal/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 UNCOMMITEDxxx
READ COMMITEDoxx
REPEATABLE READoox
SERIALIZABLEooo

数据库默认隔离级别

数据库默认隔离级别特点
MySQL (InnoDB)REPEATABLE READ通过MVCC+Next-Key Locking,实际上解决了幻读
PostgreSQLREAD COMMITTED使用MVCC,提供较好的并发性能
OracleREAD COMMITTED使用Undo表空间实现多版本读
SQL ServerREAD COMMITTED支持快照隔离(Snapshot Isolation)
SQLiteSERIALIZABLE简单但并发性能较低

锁机制

锁类型描述使用场景
共享锁 (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) ──→ 撤销修改
└──────────────────┘