面试题:MySQL 中的事务隔离级别有哪些?

MySQL 中的事务隔离级别用于控制事务之间的可见性,确保数据库在高并发场景下的数据一致性。MySQL 支持四种事务隔离级别,从低到高依次为:


1. 读未提交(Read Uncommitted)

  • 定义:允许一个事务读取另一个事务尚未提交的修改。
  • 问题
    • 脏读(Dirty Read):事务可能读取到其他事务未提交的数据(如果该事务回滚,读取的数据是无效的)。
    • 不可重复读(Non-Repeatable Read):同一事务内多次读取同一数据,结果可能不一致(其他事务提交了修改)。
    • 幻读(Phantom Read):同一事务内多次查询满足条件的记录,结果集可能增加或减少(其他事务插入/删除数据)。
  • 适用场景:对数据一致性要求极低的场景,如统计类操作,但实际很少使用。

2. 读已提交(Read Committed)

  • 定义:一个事务只能读取到其他事务已经提交的修改。
  • 解决的问题
    • 防止脏读
  • 存在的问题
    • 不可重复读:同一事务内多次读取同一数据,结果可能不一致。
    • 幻读:同一事务内多次查询结果集可能变化。
  • 实现机制
    • MVCC(多版本并发控制):通过快照读(Snapshot Read)实现非阻塞读。
    • 锁机制:写操作需要加锁(如行锁),防止脏写。
  • 适用场景:大多数数据库的默认隔离级别(如 Oracle、PostgreSQL),适合需要避免脏读但允许短时数据不一致的场景。

3. 可重复读(Repeatable Read)

  • 定义:事务在执行期间多次读取同一数据时,结果始终一致(即使其他事务提交了修改)。
  • 解决的问题
    • 防止脏读
    • 防止不可重复读
  • 存在的问题
    • 幻读(标准 SQL 的定义):但在 InnoDB 存储引擎 中通过 Next-Key Lock 机制解决了幻读问题。
  • 实现机制
    • MVCC:保证事务内读取的快照一致性。
    • Next-Key Lock:行锁 + 间隙锁,防止其他事务插入新记录(解决幻读)。
  • 适用场景:MySQL 的默认隔离级别(InnoDB),适用于大多数业务场景,如金融系统、订单处理等。

4. 串行化(Serializable)

  • 定义:所有事务依次串行执行,完全隔离。
  • 解决的问题
    • 防止脏读
    • 防止不可重复读
    • 防止幻读
  • 缺点
    • 性能开销大:事务串行执行,可能导致大量等待,降低并发性。
  • 实现机制
    • 锁机制:对所有读写操作加锁,包括范围锁(如表锁、间隙锁)。
  • 适用场景:对数据一致性要求极高且并发量较低的场景,如银行核心交易系统。

事务隔离级别与并发问题的关系

隔离级别脏读不可重复读幻读
读未提交(RU)
读已提交(RC)×
可重复读(RR)×××(InnoDB)
串行化(S)×××

如何查看和设置隔离级别?

  • 查看当前隔离级别
  -- MySQL 8.0 之前
  SELECT @@tx_isolation;
  -- MySQL 8.0 及以上
  SELECT @@transaction_isolation;
  • 设置隔离级别
  SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL
    {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE};
  • SESSION:仅对当前会话生效。
  • GLOBAL:对所有新会话生效。

选择隔离级别的原则

  1. 一致性 vs. 性能
    • 隔离级别越高,数据一致性越强,但性能损耗越大。
    • 通常选择 可重复读(RR) 或 读已提交(RC)
  2. 业务需求
    • 如果业务允许短时数据不一致(如统计类操作),可使用 RC
    • 如果业务要求严格一致性(如金融交易),可使用 RR 或 S

补充:InnoDB 中可重复读(RR)的特殊性

  • 标准 SQL 的 RR:无法完全避免幻读。
  • InnoDB 的 RR:通过 Next-Key Lock(行锁 + 间隙锁)防止幻读,实际效果等同于 Serializable,但性能优于串行化。

总结

  • 默认级别:MySQL 的 InnoDB 存储引擎默认使用 可重复读(RR),结合 MVCC 和锁机制,既能保证一致性,又能兼顾性能。
  • 选择建议:根据业务需求权衡一致性与性能,避免过度使用高隔离级别导致性能瓶颈。
THE END
喜欢就支持一下吧
点赞13 分享