MySQL InnoDB的各种隔离级别为什么在MyISAM中都无法实现?

作者:袖梨 2026-07-09
MyISAM不支持事务,因此不存在隔离级别概念;它无事务日志、无MVCC、无一致性视图,所有操作自动提交,SET TRANSACTION ISOLATION LEVEL对其无效。

MyISAM 不支持事务,所以根本不存在「隔离级别」这个概念。MySQL 的事务隔离机制(READ UNCOMMITTEDREAD COMMITTEDREPEATABLE READSERIALIZABLE)是引擎层实现的,而 MyISAM 引擎在设计上就**不提供事务支持**——它没有事务日志(undo log / redo log)、没有一致性视图(consistent read view)、也没有 MVCC 机制。所有这些,都是 InnoDB 实现隔离级别的底层基础。

MyISAM 没有事务日志,也就没有回滚和并发控制能力

事务隔离的核心前提是「事务可开始、可提交、可回滚」。而 MyISAM 所有写操作都是立即落盘的,没有 undo log,一旦 UPDATEDELETE 执行,数据就不可逆地改了。这意味着:

  • 无法定义「事务边界」,BEGINCOMMITMyISAM 表上只是被忽略的空操作
  • 没有「未提交状态」,自然谈不上「读未提交」或「脏读」
  • 没有「快照」概念,SELECT 总是读最新物理数据,无法构造一致性视图

InnoDB 的隔离级别依赖 MVCC + 锁 + 视图机制

InnoDB 实现 REPEATABLE READ(默认)靠的是:

  • 每个事务启动时生成一个 read view,记录当时活跃事务 ID 列表
  • 通过 undo log 链回溯行的历史版本
  • 配合 next-key lock 防止幻读

MyISAM 连最基本的行版本都没有,更不可能维护多版本数据或事务 ID 状态。你执行 SET TRANSACTION ISOLATION LEVEL SERIALIZABLEMyISAM 表完全无效——语句能执行成功,但实际行为仍是无锁、无隔离、无并发控制的裸读写。

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 列为 NOXASavepoints 也都是 NO。这说明它连最基础的事务接口都没实现,更别说上层的隔离逻辑。

真正容易被忽略的一点是:很多人误以为「只要开了事务,隔离级别就有用」,但实际上,**隔离级别是否生效,取决于当前表使用的存储引擎**。哪怕你在同一个数据库里混合使用 InnoDBMyISAM 表,对后者执行任何 SET TRANSACTION ISOLATION LEVEL 都不会改变其行为——它始终是「非事务性裸表」。

相关文章

精彩推荐