MySQL 事务 ACID 特性详解

4次阅读

mysql事务acid特性由innodb自动保障:原子性靠undo log实现全有或全无;一致性是约束与逻辑协同达成的合法状态;隔离性通过锁+mvcc支持四种级别;持久性依赖redo log确保提交即落盘。

MySQL 事务 ACID 特性详解

MySQL 事务的 ACID 特性,是保障数据可靠性的四根支柱——不是抽象概念,而是每笔转账、每次订单、每条关键更新背后实实在在的运行规则。它不靠人盯,而由 InnoDB 存储引擎通过底层机制自动兜底。

原子性:事务必须“全有或全无”

事务是一组 SQL 的逻辑单元,不能只执行一半。比如从 A 账户扣 100 元、再给 B 账户加 100 元,这两步必须同时成功或同时撤销。中间出错(如网络中断、磁盘满、主键冲突),整个事务就回滚,A 的钱不会少,B 的钱也不会多。

InnoDB 用 Undo Log 实现原子性:事务执行时,先记录反向操作日志;一旦失败,就按 Undo Log 把已改的数据还原回去。

  • 手动开启事务用 BEGINSTART TRANSACTION
  • 成功用 COMMIT 永久落盘,失败用 ROLLBACK 彻底撤回
  • 默认 autocommit=1 是单条语句自动提交,业务中建议设为 0,自己控制事务边界

一致性:数据库始终处于合法状态

一致性不是数据库“自己保证”的独立特性,而是原子性、隔离性、持久性共同作用的结果,最终体现为:业务规则不被破坏。例如转账前后,A+B 总余额不变;用户注册时,邮箱必须唯一、密码长度合规、状态字段只能是预设值。

它依赖:

  • 约束(主键、外键、CHECK、NOT NULL
  • 触发器和存储过程中的业务逻辑
  • 应用层与数据库协同设计(比如不绕过事务直接 UPDATE)

注意:数据库不会主动理解“余额不能为负”,但可以通过 CHECK 约束或应用校验来强制这一规则——一致性,是目标,ACID 是达成它的路径。

隔离性:并发事务互不“串场”

当多个用户同时操作同一张表甚至同一行,比如两人同时从张三账户转出 100 元,若无隔离,可能都读到余额 1000、都算出 900、都写回去,结果变成 900 而非预期的 800——这就是脏写。

MySQL 通过 锁 + MVCC(多版本并发控制) 实现不同级别的隔离:

  • 读未提交(Read Uncommitted):能看到别人还没提交的数据,基本不用
  • 读已提交(Read Committed):只读已提交数据,但同一事务内多次读可能结果不同(不可重复读)
  • 可重复读(Repeatable Read,默认):事务启动时拍快照,后续读都基于该快照,避免不可重复读;InnoDB 还用 Next-Key Lock 防止幻读
  • 串行化(Serializable):最高隔离,所有读写加锁排队,性能差,仅极端场景用

查当前隔离级别:select @@transaction_isolation;

持久性:提交即“钉死在磁盘上”

一旦 COMMIT 成功返回,哪怕下一秒服务器断电、进程崩溃,这笔修改也绝不会丢。这不是靠运气,而是 InnoDB 的 Redo Log 在起作用。

流程是:事务修改数据 → 先写 Redo Log(顺序 I/O,极快)→ 再异步刷入数据文件(随机 I/O,较慢)。崩溃恢复时,MySQL 重放 Redo Log 中已提交但未写入数据文件的操作。

  • Redo Log 是循环写入的物理日志,大小固定,由 innodb_log_file_size 控制
  • 它不记录“怎么改”,只记录“在哪个页、哪个偏移量、改成什么值”
  • 配合双写缓冲(Doublewrite Buffer)还能防止页写入半截导致数据页损坏
text=ZqhQzanResources