MySQL面试题 - MySQL默认的事务隔离级别是什么?为什么选择这个级别?

回答重点

MySQL默认的隔离级别是可重复读(RepeatableRead),即RR。

原因是为了兼容早期binlog的statement格式问题,如果是使用读已提交、读未提交等隔离级别,使用了statement格式的binlog会导致主从(备)数据库数据不一致问题。


事务隔离级别概述

在数据库系统中,事务隔离级别是指多个事务同时执行时,一个事务对其他事务的可见性程度。MySQL支持四种标准的事务隔离级别:

  1. 读未提交(READ UNCOMMITTED)
  2. 读已提交(READ COMMITTED)
  3. 可重复读(REPEATABLE READ)
  4. 串行化(SERIALIZABLE)
事务隔离级别
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE

MySQL的默认隔离级别

MySQL的默认事务隔离级别是REPEATABLE READ(可重复读)。这一点可以通过以下SQL命令验证:

SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;

在MySQL 5.7及以后版本中,变量名改为transaction_isolation

SELECT @@GLOBAL.transaction_isolation, @@SESSION.transaction_isolation;

为什么选择REPEATABLE READ作为默认级别?

MySQL选择REPEATABLE READ作为默认隔离级别主要基于以下几个原因:

1. 平衡一致性与性能

一致性
SERIALIZABLE
REPEATABLE READ
READ COMMITTED
性能

REPEATABLE READ在保证较高数据一致性的同时,性能开销相对合理,是MySQL在一致性和性能之间的折中选择。

2. 避免不可重复读问题

在REPEATABLE READ级别下,一个事务内多次读取同一数据会得到相同的结果,避免了READ COMMITTED级别下的不可重复读问题。

事务1 数据库 事务2 BEGIN SELECT balance FROM accounts WHERE id=1 返回1000 BEGIN UPDATE accounts SET balance=900 WHERE id=1 COMMIT SELECT balance FROM accounts WHERE id=1 仍返回1000(可重复读) 事务1 数据库 事务2

3. MySQL的MVCC实现

MySQL通过多版本并发控制(MVCC)机制实现了REPEATABLE READ,这种实现方式:

  • 读操作不阻塞写操作
  • 写操作不阻塞读操作
  • 通过版本链维护数据的历史版本
MVCC机制
当前版本
版本链
历史版本1
历史版本2

4. 与InnoDB存储引擎的适配

InnoDB作为MySQL的默认存储引擎,其设计优化了REPEATABLE READ级别下的性能:

  • 使用next-key锁避免幻读
  • 高效的undo日志管理
  • 非锁定一致性读

REPEATABLE READ的特点

优点

  1. 事务内多次读取数据结果一致
  2. 避免了脏读和不可重复读
  3. 在InnoDB中通过next-key锁也避免了幻读
  4. 性能优于SERIALIZABLE级别

缺点

  1. 比READ COMMITTED级别有更高的锁开销
  2. 可能持有锁时间更长,增加死锁概率
  3. 需要更多的系统资源维护版本信息

如何更改隔离级别

如果需要更改隔离级别,可以使用以下命令:

-- 全局更改
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 会话级别更改
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 仅对下一个事务生效
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

不同隔离级别的比较

READ UNCOMMITTED
其他级别
READ UNCOMMITTED/READ COMMITTED
REPEATABLE READ/SERIALIZABLE
READ UNCOMMITTED/READ COMMITTED/REPEATABLE READ
SERIALIZABLE
隔离级别
脏读
不可重复读
幻读
可能
不可能
可能
不可能
可能
不可能

实际应用建议

  1. 保持默认:大多数应用使用默认的REPEATABLE READ即可
  2. 需要更高并发:可考虑降为READ COMMITTED
  3. 严格要求一致性:可升为SERIALIZABLE
  4. 报表系统:可能需要SNAPSHOT隔离(某些数据库支持)

总结

MySQL选择REPEATABLE READ作为默认事务隔离级别,是在数据一致性和系统性能之间做出的合理权衡。这种级别能够满足大多数应用场景的需求,避免了常见的并发问题,同时保持了较好的性能表现。开发者应当理解不同隔离级别的特性,根据应用的具体需求做出适当选择。

Logo

一站式 AI 云服务平台

更多推荐