很多开发者在学习MySQL隔离级别时,往往只记住了READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE这四种标准隔离级别,并默认认为只要通过SET TRANSACTION ISOLATION LEVEL命令设置,数据库就会按照预期工作。然而,一个容易被忽视的关键点是:MySQL的隔离级别并非全局开关,而是依赖于存储引擎的具体实现。如果您的表使用的是MyISAM,那么这些隔离级别实际上毫无意义——即使语句执行成功,底层行为也不会发生任何改变。

首先明确结论:MyISAM 存储引擎不支持事务,因此根本不存在所谓的“隔离级别”概念。MySQL的隔离机制由存储引擎层实现,而MyISAM 在设计上就**不提供事务支持**——它既没有事务日志(undo log / redo log),也没有一致性视图(consistent read view),更缺乏MVCC(多版本并发控制)机制。而这些正是InnoDB实现隔离级别的底层基础。
MyISAM 缺乏事务日志,导致无法实现回滚与并发控制
事务隔离的核心前提是事务能够开始、提交和回滚。然而,MyISAM 的所有写操作都是立即写入磁盘,没有 undo log 支持。一旦执行 UPDATE 或 DELETE,数据就会永久修改,无法撤销。这意味着:
- 无法定义事务边界,
BEGIN和COMMIT在MyISAM表上被视为无效操作。 - 没有“未提交状态”,因此谈不上“读未提交”或“脏读”问题。
- 没有“快照”概念,
SELECT总是读取最新物理数据,无法构建一致性视图。
InnoDB 的隔离级别依赖 MVCC、锁与视图机制
相比之下,InnoDB 实现 REPEATABLE READ(默认隔离级别)依赖三大组件:每个事务启动时创建一个 read view,记录当前活跃事务 ID 列表;通过 undo log 链回溯行的历史版本;同时使用 next-key lock 防止幻读。而 MyISAM 连最基本的行版本控制都没有,更无法维护多版本数据或事务 ID 状态。即使执行 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE,对 MyISAM 表也完全无效——语句虽然执行成功,但实际行为仍然是缺乏锁、隔离和并发控制的裸读写。
MyISAM 的并发模型仅依赖表级锁,且不区分读写事务
MyISAM 的并发控制机制非常基础:
SELECT操作加共享表锁(允许并发读取)。INSERT/UPDATE/DELETE操作加独占表锁(阻塞所有其他操作)。- 没有行锁、间隙锁或意向锁。
- 即使两个
SELECT同时执行,它们看到的数据也可能处于不同时间点——因为中间可能被另一个UPDATE全表覆盖。
在这种模型下,“隔离”仅体现为“串行化写”,而非事务意义上的“读写隔离”。所谓的“可重复读”在 MyISAM 中根本无法保证:在事务 A 中两次执行 SELECT,如果中间被事务 B 的 UPDATE 插入,第二次结果必然不同。
SHOW ENGINES 输出明确显示 MyISAM 不支持事务
您可以通过运行 SHOW ENGINES; 查看输出,其中会显示如下一行:
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
其中 Transactions 列为 NO,XA 和 Savepoints 也都是 NO。这表明 MyISAM 连最基础的事务接口都没有实现,更不用说上层的隔离逻辑了。
真正容易被忽略的一点是:很多开发者误以为“只要开启了事务,隔离级别就会生效”,但实际上,**隔离级别是否生效取决于当前表所使用的存储引擎**。即使在同一数据库中混合使用 InnoDB 和 MyISAM 表,对后者执行任何 SET TRANSACTION ISOLATION LEVEL 都不会改变其行为——它始终是一个“非事务性裸表”。
