真正支持事务的存储引擎只有innodb和ndb(mysql cluster);myisam等其他引擎虽可执行start transaction但rollback无效,不满足acid。

哪些存储引擎真正支持事务?
MySQL中**只有 InnoDB 和 NDB(MySQL Cluster)原生支持完整 ACID 事务**,其他常见引擎如 MyISAM、Memory、CSV、Archive 都不支持事务——哪怕执行 START TRANSACTION,后续的 ROLLBACK 也完全无效,数据照常写入。
实操中容易踩的坑:
• 创建表时没显式指定 ENGINE=InnoDB,而 MySQL 版本低于 5.5(或被手动改过默认引擎),结果用了 MyISAM,误以为“开了事务就安全”;
• 在 MyISAM 表上执行 COMMIT 或 ROLLBACK 不报错,但实际无任何效果,日志里也看不到事务行为;
• NDB 虽支持事务,但仅限于 NDB Cluster 环境,单机 MySQL 实例根本用不了。
InnoDB 事务到底靠什么保证?
InnoDB 的事务能力不是“开关式”的附加功能,而是由底层机制深度耦合实现的:
• MVCC(多版本并发控制)支撑 READ COMMITTED 和 REPEATABLE READ 隔离级别,避免读写阻塞;
• 每行数据自带隐藏的事务 ID 和回滚指针,ROLLBACK 本质是按 undo log 回退到前镜像;
• 崩溃恢复依赖 redo log,即使 mysqld 异常退出,未刷盘的事务也能在重启时重做或回滚。
注意:如果你把 innodb_flush_log_at_trx_commit 设为 0 或 2,虽然写入快,但可能丢失最近 1 秒内的已提交事务——这不是事务失效,而是持久性(D)妥协,需按业务容忍度权衡。
MyISAM 声称“原子性”,为什么不算事务?
MyISAM 单条语句(如 UPDATE)确实不会“写一半”,但这只是文件系统层面的原子写,和事务的原子性(A)有本质区别:
• 它无法将多条 SQL 绑定为一个逻辑单元,INSERT + UPDATE + DELETE 之间没有回滚锚点;
• 没有隔离级别概念,SELECT 可能读到其他事务中途写入的脏数据(即使没显式加锁);
• 表级锁导致高并发下极易阻塞,UPDATE 期间整个表不可读不可写。
典型误用场景:
• 用 MyISAM 存用户余额表,靠应用层 try-catch 模拟事务——一旦中间出错,数据库已残留不一致状态;
• 把 MyISAM 的 COUNT(*) 快误认为“更可靠”,其实它连实时行数都不保证(如并发 DELETE 后缓存未刷新)。
怎么一眼确认当前表是否真支持事务?
别只看建表语句或文档描述,直接查元数据最准:
• 执行 SHOW CREATE TABLE `your_table`;,检查输出里是否有 ENGINE=InnoDB;
• 运行 SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'your_table';;
• 更彻底:启动事务后故意让第二条语句出错,再 SELECT 查数据是否回滚——这是唯一验证事务生效的硬标准。
特别提醒:MySQL 8.0+ 默认字符集改为 utf8mb4,但某些老迁移脚本仍带 ENGINE=MyISAM DEFAULT CHARSET=utf8,复制粘贴时极易忽略引擎声明,结果新建表全掉坑里。










