mysql事务有哪些特性_mysql事务ACID原理说明

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

MySQL事务的四个核心特性到底指什么

MySQL事务的ACID不是抽象概念,而是InnoDB引擎在崩溃恢复、并发读写、异常中断等真实场景下必须守住的四条底线。它们各自解决一个具体问题:

原子性(Atomicity):保证“全成功或全失败”。比如转账时扣款和存款必须绑定,不能只执行一半。 一致性(Consistency):不是数据库自动保证的“业务正确”,而是靠原子性+隔离性+持久性+约束(如外键、CHECK)共同支撑的最终结果。例如转账前后总金额不变,是代码逻辑+事务机制+约束校验一起达成的。 隔离性(Isolation):解决并发读写冲突。默认
REPEATABLE READ
级别下,同一个事务内多次
SELECT
看到的数据版本一致,靠MVCC + undo log实现;而写操作则依赖行锁、间隙锁防止幻读。
持久性(Durability):只要
COMMIT
返回成功,即使立刻断电,重启后数据也不会丢——这靠的是
redo log
刷盘(由
innodb_flush_log_at_trx_commit=1
保障)。

undo log和redo log分别管什么,为什么不能少

很多人混淆这两个日志,其实分工非常明确:

undo log
是“回滚凭证”:记录修改前的旧值(比如
UPDATE
前的整行数据),用于
ROLLBACK
或MVCC构造历史版本。它存在系统表空间里,事务提交后不会立刻删除,要等Purge线程异步清理。
redo log
是“重做凭证”:记录物理页修改(比如“第5号页偏移量128处写入0x3A”),只管“怎么把内存里的脏页变化安全落地”。它不负责回滚,也不参与MVCC,只服务崩溃恢复。
两者缺一不可:没有
undo log
,事务失败就无法回退;没有
redo log
,Buffer Pool里的修改一旦宕机就全丢,
COMMIT
就成空话。

为什么SET autocommit=0后,DDL语句还会自动提交

这是InnoDB的硬性规则,不是bug。所有DDL操作(如

CREATE TABLE
ALTER TABLE
DROP INDEX
)都会隐式触发
COMMIT
,哪怕你已经
START TRANSACTION
了。

原因在于DDL会重建表结构或元数据,涉及存储引擎层状态变更,无法被普通事务包裹。 后果很实际:如果你在事务中先
UPDATE
ALTER TABLE
,前面的
UPDATE
会立刻生效,无法通过后续
ROLLBACK
撤销。
规避方法只有两个:把DDL单独放在独立连接里执行,或用
pt-online-schema-change
等工具做无锁变更。

隔离级别选错,查不到数据却以为是BUG

最常见踩坑是误以为

READ COMMITTED
REPEATABLE READ
“更安全”,结果发现同一事务内两次
SELECT
结果不同,怀疑数据丢了。

REPEATABLE READ
(InnoDB默认):事务启动时生成一个全局
Read View
,后续所有
SELECT
都基于这个快照,所以不会不可重复读。
READ COMMITTED
:每次
SELECT
都生成新
Read View
,能看到其他事务刚
COMMIT
的数据——这正是“不可重复读”的定义,但它是符合标准的正常行为。
真正要注意的是:如果业务依赖“事务内读一致性”(比如先查余额再扣款),就不能随意切到
READ COMMITTED
,否则可能多扣或少扣。
事务的复杂点不在语法,而在日志生命周期、锁范围、MVCC快照时机这些底层协同细节。比如
undo log
没被Purge完,会导致
history list
堆积,拖慢查询;又比如
gap lock
只在
REPEATABLE READ
下生效,换到
READ COMMITTED
后幻读风险就回来了——这些都不是调个参数就能解决的,得看懂它在做什么。

相关推荐