MySQL事务处理只能选择InnoDB,因为MyISAM等引擎未实现事务底层能力,无undo log、redo log和binlog,不支持原子性与持久性,忽略START TRANSACTION、ROLLBACK等语句,且无外键与隔离级别支持。

MySQL事务处理只能选择InnoDB,不是因为其他引擎“不够快”,而是它们根本没实现事务的底层能力——连START TRANSACTION都只是静默忽略。
MyISAM执行START TRANSACTION会发生什么
它什么都不会做。没有事务日志、没有undo log、没有两阶段提交支持。你写BEGIN、COMMIT或ROLLBACK,MySQL会照单接收但不执行任何事务语义操作。现象是:
- UPDATE成功后崩溃,数据直接丢失,无法回滚
- 应用层
try-catch捕获异常后调用ROLLBACK,实际什么也没撤回 - 主从复制中,从库遇到MyISAM表写入失败时SQL线程直接中断,必须人工
REPAIR TABLE
事务原子性依赖InnoDB独有的三类日志机制
ACID里的“A(原子性)”和“D(持久性)”不是靠代码逻辑模拟出来的,而是由物理日志保障的:
-
undo log:记录事务前镜像,用于ROLLBACK或崩溃后回滚未提交事务 -
redo log:预写式日志,确保已COMMIT的数据即使断电也能前滚恢复 -
binlog(配合sync_binlog=1):与redo log协同实现XA事务一致性,这是分布式事务的基础
MyISAM没有其中任何一种日志结构,它的.MYD/.MYI文件是裸数据直写,崩溃即损坏。
外键和隔离级别在MyISAM里压根不存在
哪怕你建表时写了FOREIGN KEY,MyISAM也会直接忽略并静默删掉该定义——SHOW CREATE TABLE里根本不会出现。更关键的是:
- MyISAM不支持任何事务隔离级别,
SET TRANSACTION ISOLATION LEVEL无效 - 它的
SELECT永远是当前读,高并发下必然看到不一致中间态(比如库存扣减过程中被其他会话读到负数) - InnoDB的MVCC快照读机制,在MyISAM里完全不可用,所有读写都互相阻塞
检查和迁移必须动手验证,不能信“默认”
很多线上库看似用了InnoDB,实则混着MyISAM表跑,隐患极大。务必执行:
- 查全库引擎:
SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE ENGINE != 'InnoDB'; - 建表强制指定:
CREATE TABLE t (...) ENGINE=InnoDB;,别依赖default_storage_engine - 存量迁移用
ALTER TABLE t ENGINE=InnoDB;,但注意:该操作会锁表重写全部数据,必须在低峰期执行
真正容易被忽略的是:事务不是开关,而是整套日志+锁+恢复机制的闭环。一旦某张表落在MyISAM上,整个事务链就断了——不是慢一点,是原子性彻底失效。


















