在数据库系统中,事务(Transaction)是保证数据一致性的重要机制。MySQL 通过 ACID 特性 确保事务的可靠性,并通过 不同的事务隔离级别 控制并发事务对数据的影响。本篇文章将详细介绍 MySQL 的 ACID 特性,并解析 事务的四种隔离级别(RU、RC、RR、S),帮助开发者理解 如何在保证数据一致性的同时优化数据库性能


1. MySQL 的 ACID 特性

ACID 是数据库事务必须满足的四个关键特性,分别是:

ACID 特性含义作用
A(原子性,Atomicity)事务中的操作要么全部成功,要么全部失败确保事务完整执行,防止数据部分提交
C(一致性,Consistency)事务执行前后,数据库保持一致状态事务不会破坏数据库的完整性
I(隔离性,Isolation)并发事务之间互不干扰控制事务间的可见性,防止数据竞争
D(持久性,Durability)事务提交后,数据永久保存即使系统崩溃,数据也不会丢失

2. 事务隔离级别(RU/RC/RR/S)

MySQL 提供四种事务隔离级别,用于控制 并发事务之间的可见性,分别是:

隔离级别可能发生的问题性能默认值(InnoDB)
RU(Read Uncommitted,读未提交)可能发生 脏读最高
RC(Read Committed,读已提交)可能发生 不可重复读
RR(Repeatable Read,可重复读)可能发生 幻读✅(默认)
S(Serializable,可串行化)不会发生任何问题,但并发性最差

3. 事务隔离级别详解(RU/RC/RR/S)

3.1 读未提交(Read Uncommitted,RU)

特性

  • 事务可以读取 其他事务未提交的数据
  • 可能发生脏读(Dirty Read),即一个事务读取到 另一个事务尚未提交的数据

示例

事务 A 修改了 balance,但尚未提交:

-- 事务 A
START TRANSACTION;
UPDATE accounts SET balance = 5000 WHERE id = 1;
-- 事务 A 尚未提交

此时,事务 B 读取 balance

-- 事务 B
SELECT balance FROM accounts WHERE id = 1;
-- 结果:balance = 5000

如果事务 A 回滚,事务 B 读取的数据将变得无效(脏数据)。

适用场景

  • 适用于 对数据一致性要求不高的场景,如日志记录、临时数据存储。
  • 一般不建议在生产环境使用,因为数据可能不可靠。

3.2 读已提交(Read Committed,RC)

特性

  • 事务 只能读取其他事务已提交的数据,避免了 脏读
  • 可能发生不可重复读(Non-repeatable Read),即 同一个事务内多次查询相同数据,结果可能不同

示例

事务 A 先查询 balance,事务 B 修改并提交了 balance,事务 A 再次查询数据,发现值已变更。

-- 事务 A:第一次查询
SELECT balance FROM accounts WHERE id = 1;
-- 结果:balance = 1000

-- 事务 B:修改并提交
START TRANSACTION;
UPDATE accounts SET balance = 5000 WHERE id = 1;
COMMIT;

-- 事务 A:再次查询
SELECT balance FROM accounts WHERE id = 1;
-- 结果:balance = 5000(发生不可重复读)

适用场景

  • 适用于 大多数应用,如 银行转账、支付系统,避免读取未提交数据导致数据不一致。
  • Oracle、SQL Server 默认使用 Read Committed 作为事务隔离级别

3.3 可重复读(Repeatable Read,RR)MySQL 默认

特性

  • 事务内 多次读取相同的数据,保证读取结果一致,避免 脏读不可重复读
  • 可能发生幻读(Phantom Read),即事务查询的数据范围发生变化,如 新增数据未被感知

示例

事务 A 读取表 accounts,事务 B 插入新数据,事务 A 再次查询,发现结果多了一行。

-- 事务 A:第一次查询
SELECT * FROM accounts WHERE balance > 1000;
-- 结果:3 行数据

-- 事务 B:新增一条数据并提交
START TRANSACTION;
INSERT INTO accounts(id, balance) VALUES (4, 2000);
COMMIT;

-- 事务 A:再次查询
SELECT * FROM accounts WHERE balance > 1000;
-- 结果:4 行数据(发生幻读)

MySQL InnoDB 如何避免幻读?

  • MySQL 通过 MVCC(多版本并发控制) 实现 Repeatable Read,在 SELECT 时读取快照版本,而不是最新数据。

适用场景

  • 适用于金融交易、订单系统等场景,确保事务内部数据一致。
  • MySQL 默认采用 Repeatable Read(RR),性能和一致性较为平衡。

3.4 串行化(Serializable,S)

特性

  • 最高级别隔离,完全避免 脏读、不可重复读、幻读
  • 强制事务串行执行,每个事务必须等前一个事务完成后才能执行,导致 并发性能极低

示例

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
SELECT * FROM accounts WHERE balance > 1000;
  • 所有 SELECT 语句都会加共享锁(S 锁),阻止其他事务的 INSERT/UPDATE/DELETE

适用场景

  • 适用于 高一致性要求的金融系统,但性能开销大,通常不会用于高并发环境。

4. 结论

  • ACID 保障事务的可靠性,MySQL 默认支持事务的 原子性、一致性、持久性
  • MySQL 提供 4 种事务隔离级别,默认是 Repeatable Read(RR),适用于大多数业务场景。
  • 不同隔离级别适用于不同的应用需求,开发者需要根据业务需求权衡 数据一致性与性能

📌 有什么问题和经验想分享?欢迎在评论区交流、点赞、收藏、关注! 🎯

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐