
ACID 是数据库事务的四个核心特性确保数据操作的可靠性与正确性Atomicity原子性事务是不可分割的最小执行单元。若事务中任一操作失败则整个事务回滚数据库状态恢复到事务开始前如同从未执行过该事务。实现通常依赖于日志如 undo log和回滚机制。Consistency一致性事务必须使数据库从一个一致状态转移到另一个一致状态。它不是数据库自动保证的而是由应用逻辑 数据库约束如主键、外键、CHECK 约束、触发器等共同维护。ACID 中的 C 是目标而非机制A、I、D 是达成 C 的技术保障。Isolation隔离性并发执行的多个事务应如同串行执行一样互不干扰。数据库通过隔离级别Read Uncommitted、Read Committed、Repeatable Read、Serializable和并发控制机制如锁机制、MVCC 多版本并发控制来平衡性能与隔离强度。常见并发问题包括脏读、不可重复读、幻读不同级别对此有不同防护能力。Durability持久性一旦事务成功提交COMMIT其对数据库的修改将永久保存即使系统崩溃也不会丢失。通常通过写入**redo log重做日志**并刷盘fsync实现确保故障后可恢复已提交事务。✅ 补充说明现代数据库如 PostgreSQL、MySQL InnoDB普遍采用MVCC 行级锁实现高并发下的强隔离如 RR 级别下避免不可重复读配合间隙锁/Next-Key Lock 防幻读而 Serializable 级别可能通过严格的锁或序列化调度如 SSI实现真正串行语义。-- 示例MySQL 中查看当前隔离级别SELECTtransaction_isolation;-- 设置会话隔离级别如可重复读SETSESSIONTRANSACTIONISOLATIONLEVELREPEATABLEREAD;MVCCMulti-Version Concurrency Control多版本并发控制是现代关系型数据库如 PostgreSQL、MySQL InnoDB实现高并发、非阻塞读的核心机制。它通过为数据行维护多个历史版本使不同事务能“看到”各自快照下的数据从而在不加读锁的前提下实现可重复读Repeatable Read等隔离级别。✅ 核心思想“读不阻塞写写不阻塞读”每个事务基于其启动时刻的**一致性视图consistent snapshot**访问数据该视图由当时活跃事务ID集合决定事务只看到在其开始前已提交的版本或自身修改的版本。 关键组件以 InnoDB 为例组件说明隐藏字段每行记录包含两个隐藏列•DB_TRX_ID最后修改该行的事务ID•DB_ROLL_PTR指向 undo log 中该行前一版本的指针构成版本链undo log回滚段存储历史版本数据用于构建旧快照、事务回滚及 MVCC 可见性判断read view读视图事务启动时创建记录当前活跃事务ID列表m_ids、最小未分配事务IDmin_trx_id、最大已存在事务IDmax_trx_id等是可见性判断的依据 版本链与可见性规则InnoDB 的 Repeatable Read版本链形成当事务 T1 更新某行时InnoDB 不覆盖原数据而是将旧值写入 undo log生成旧版本更新当前行的DB_TRX_ID T1DB_ROLL_PTR指向 undo log 中的上一版本→ 多次更新形成从新到旧的单向链表最新版在最前可见性判断核心逻辑对于某行的某个版本事务 T 根据其read view判断是否可见若 version_trx_id T.id → 自身修改可见 ✅ 若 version_trx_id read_view.min_trx_id → 已提交且早于T开始可见 ✅ 若 version_trx_id read_view.max_trx_id → 属于未来事务不可见 ❌ 若 version_trx_id ∈ read_view.m_ids → 该版本由未提交/正在运行的事务产生不可见 ❌→ 事务沿版本链从新到旧遍历找到第一个满足可见条件的版本即为本次查询所见值。可重复读的保障RR 级别下read view在事务第一次执行 SELECT 时创建非每次查询后续查询复用同一视图因此即使其他事务提交了新版本当前事务仍“固守”初始快照保证多次读结果一致 补充PostgreSQL 的 MVCC 更彻底——每个事务启动即冻结全局事务ID快照Snapshot所有查询均基于该快照而 InnoDB 的read view是轻量级结构但语义等价。 示例简析InnoDB-- 假设事务IDT1100, T2101, T3102-- 初始row(id1, val10), DB_TRX_ID99已提交T1:UPDATEtSETval20WHEREid1;-- 生成新版本val20, DB_TRX_ID100, DB_ROLL_PTR→旧版本T2:UPDATEtSETval30WHEREid1;-- 再生成val30, DB_TRX_ID101, DB_ROLL_PTR→val20版本T3:SELECT*FROMtWHEREid1;-- T3启动时read view m_ids[100,101]若T1/T2未提交→ 最新版本DB_TRX_ID101∈ m_ids → 不可见 → 查看上一版本DB_TRX_ID100∈ m_ids → 不可见 → 查看原始版本DB_TRX_ID99min_trx_id → 可见 ⇒ 返回 val10✅ 总结MVCC 通过版本链 事务快照read view 精确可见性规则让每个事务拥有独立的数据时间视图在无读锁前提下天然支持可重复读同时极大提升并发吞吐。