mysql数据库事务隔离级别是什么_mysql并发控制说明

来源:这里教程网 时间:2026-02-28 20:49:57 作者:

MySQL事务隔离级别到底控制什么

它控制的是:**一个事务能看到其他并发事务做到哪一步的数据**。不是“能不能读”,而是“读到的是哪个时间点、谁提交过的数据”。本质是数据库在性能和一致性之间做的权衡。

MySQL默认用

REPEATABLE READ
,但很多人误以为它能完全避免幻读——其实只在配合间隙锁(Gap Lock)时才成立;一旦用了
READ COMMITTED
,间隙锁就失效,幻读立刻出现。

四种隔离级别对应的真实行为差异

别死记“脏读/不可重复读/幻读”定义,看实际表现更准:

READ UNCOMMITTED
:SELECT 不加任何版本过滤,直接读最新行数据(哪怕在别的事务里还没 COMMIT),
SELECT
可能返回回滚前的中间态
READ COMMITTED
:每次
SELECT
都生成新 Read View,所以同一事务内两次查同一条记录,可能得到不同结果(比如另一事务刚 UPDATE+COMMIT)
REPEATABLE READ
:整个事务只建一次 Read View,保证“可重复读”;但对
WHERE id BETWEEN 10 AND 20 FOR UPDATE
这类范围查询,InnoDB 会自动加间隙锁,堵住插入,防幻读
SERIALIZABLE
:所有普通
SELECT
都隐式转成
SELECT ... LOCK IN SHARE MODE
,写操作冲突时直接等锁,几乎无并发

怎么查和改当前隔离级别

别信配置文件里写的,运行时可能被连接层覆盖。必须查当前会话真实值:

SELECT @@transaction_isolation;

修改只对当前会话生效,重启即丢:

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

注意:

SET GLOBAL
改全局会影响后续新连接,但**不会改变已有连接的级别**;线上调参前务必确认连接池是否复用长连接。

最容易被忽略的坑:RR 级别下幻读没消失?

很多人测试发现

REPEATABLE READ
下还是有幻读——十有八九是因为用了非唯一索引或没走索引:

只有在**索引列上做等值或范围查询 + FOR UPDATE / LOCK IN SHARE MODE** 时,InnoDB 才会启用临键锁(Next-Key Lock) 如果
WHERE
条件没命中索引,会退化为表锁;如果条件命中的是二级索引且没包含主键,间隙锁范围可能比预期大得多
SELECT ... FOR UPDATE
时若未匹配到记录,InnoDB 仍会在扫描区间加间隙锁——这点常被当成“莫名卡住”的原因

真正稳住幻读的组合是:

REPEATABLE READ
+ 唯一/主键等值条件 + 显式加锁。其它情况,别轻信“MySQL 已解决幻读”。

相关推荐