MySQL 事务如何工作,ACID 特性如何保证?

考查重点:回滚、恢复与并发隔离。undo 支持回滚和版本,redo 支持持久恢复,锁与 MVCC 管并发,约束守业务合法性;保证还受日志配置影响

本题目录

参考答案

核心回答

以 MySQL 8.4 的 InnoDB 普通持久表为例,事务把一组操作放进同一个提交或回滚边界,再由 undo、redo、MVCC、锁和约束共同支撑 ACID。

默认 autocommit=1,普通 SQL 语句各自构成一个事务。需要“扣库存和写订单一起成功”时,应显式开启事务,全部成功后 COMMIT,失败则 ROLLBACK。

  • 原子性 A:事务内的修改作为一个整体提交,回滚时撤销未提交的修改。InnoDB 通过 undo 记录回滚所需的信息;崩溃恢复时也要处理未完成事务,避免留下半个事务的结果。
  • 一致性 C:事务应让数据从满足约束和业务规则的状态,变成另一个满足规则的状态。唯一键、外键等约束由数据库检查,“库存不能超卖”等规则还需要应用写对 SQL、判断执行结果,并选择合适的并发控制。
  • 隔离性 I:控制并发事务之间能看到什么、哪些操作需要互相等待。InnoDB 通过 MVCC 提供一致性读,通过锁协调加锁读和写操作,具体行为取决于隔离级别。
  • 持久性 D:事务成功提交后,即使进程崩溃,也应能恢复其结果。核心是 redo 与预写日志原则:相关日志先持久化,数据页可以稍后刷盘,重启时根据日志恢复。

所以不能把 ACID 全归给 redo,也不能说“开了事务就天然满足所有业务规则”。事务边界、SQL 逻辑、隔离方式和持久化配置都要配合。

进一步解释

一次更新中,日志和数据页怎样配合?

更新通常先作用于 Buffer Pool 中的数据页,形成脏页,同时生成相应的 undo 和 redo 信息。undo 支持撤销,也为 MVCC 提供历史版本;redo 支持崩溃后的重做。它们的职责不同,undo 也不是把原 SQL 换个方向再执行一遍。

提交不需要把本事务涉及的所有脏页立刻写回数据文件。采用持久化提交策略时,先保证恢复所需的日志落盘,再向客户端确认;之后后台逐步刷脏页。崩溃恢复既要恢复尚未写入数据文件的修改,也要处理未提交事务,不能简单理解成“redo 中只会有已提交事务”。

开启 binlog 时,还要协调 InnoDB 事务与 binlog 的提交结果,供崩溃恢复和复制使用。MySQL 的内部两阶段提交处理的是这两者的协同,并不会自动把 Redis、HTTP 调用或其他数据库也纳入同一个本地事务。

隔离为什么同时需要 MVCC 和锁?

在 READ COMMITTED 下,普通一致性读每次使用新的快照;在默认的 REPEATABLE READ 下,同一事务的普通一致性读通常沿用第一次这类读取建立的快照。不能把快照建立时间一概说成执行 BEGIN 的那一刻。

SELECT ... FOR UPDATE 和更新语句采用加锁规则,不能套用普通快照读的全部结论。它们可能等待冲突事务结束;锁的范围还受索引、查询条件和隔离级别影响。MVCC 减少了普通读与写之间的阻塞,并没有消除所有并发冲突。

用下单说明事务边界

一个参考流程是:开启事务,按“库存足够”的条件扣减库存,检查影响行数,成功后写入订单,最后提交。扣减失败则结束流程;订单写入失败则回滚前面的扣减。条件更新及结果判断负责业务正确性,事务负责这组数据库修改一起提交或撤销。

数据库报错时,要区分“当前语句失败”和“整个事务已经回滚”。不同错误的处理方式不同,应用不能捕获异常后不作判断就继续提交。部分 DDL 还会隐式提交,也不能随意夹进上述业务事务。

常见追问

怎样配置才能尽量保住已确认提交的数据?

对需要持久化提交的 InnoDB 业务,通常使用 innodb_flush_log_at_trx_commit=1;启用 binlog 时配合 sync_binlog=1。放宽刷盘策略可能丢失已确认提交的近期事务,损失窗口也不应机械写成“最多一秒”。这些保证仍以操作系统和存储正确兑现刷盘为前提,不能替代备份及容灾。

为什么事务都成功了,库存仍可能不对?

事务可以原子地提交一段写错的业务逻辑。例如先普通查询库存,再无条件按旧值覆盖,即使两步都在事务中,也可能产生并发问题。应把业务条件放进更新语句,或采用合适的锁、版本校验等方式,而不是只依赖 BEGIN 和 COMMIT。

参考资料

相关面经

9 篇

拼多多、荣耀、立元科技、得物、华橙

面经合集
查看原面经 →
数据库事物

字节跳动

Agent 开发
校招秋招一面、二面、三面
查看原面经 →
Redis 有事务吗?它与 MySQL 事务有什么区别?

蚂蚁集团

面经合集
查看原面经 →
数据库的四个特性,具体分别是怎么去实现的

蚂蚁集团

面经合集
查看原面经 →
ACID,原子性一致性怎么实现的

科大讯飞

Java 开发工程师
秋招一面、二面
查看原面经 →
MySQL的事务
展开剩余 4 篇面经

中科创达

后端开发工程师(AI / RAG 方向)
查看原面经 →
数据库事务的 ACID 四大特性分别是什么?

虾皮

秋招一面
查看原面经 →
你提到事务,详细讲讲你项目中事务怎么做的

字节跳动

后端开发工程师(AI)
实习一面
查看原面经 →
事务了解吗?简单讲一下?

字节跳动

AI 开发工程师
实习一面
查看原面经 →
mysql事务

收录题集

1 个来源,共1 份题集

系统设计与后端基础

阿东玩 AI · AgentGuide · 1 条原题

查看题集 →

相关题目

4 题