mysql事务有哪些特性_mysqlACID特性说明

2次阅读

mysql事务必须满足ACID四约束才算真正可用:原子性靠undo log实现全成或全败;一致性依赖约束与事务协同保障业务规则;隔离性由MVCC与锁机制在REPEATABLE READ等级别下平衡并发与性能;持久性通过redo log刷盘确保提交即落地。

mysql事务有哪些特性_mysqlACID特性说明

MySQL 事务不是“有事务功能”就完事了,它必须满足 ACID 四个硬性约束才算真正可用。不支持 ACID 的所谓“事务”,比如 MyISAM 引擎的 BEGIN/COMMIT,只是语法上像,实际没原子性、没回滚、没隔离——等于裸奔。


原子性(Atomicity):要么全成,要么白干,中间状态不能留

这是事务最基础的底线。比如转账:扣 A 账户、加 B 账户,这两步必须捆在一起。如果扣款成功但加款失败,数据库绝不能只留下“A 少了钱、B 没多钱”的残缺状态。

  • undo log 实现:每条 UPDATE/INSERT/delete 都先记下“怎么反向撤销”,出错时直接按 log 倒带
  • START TRANSACTION 后,任何语句报错(如主键冲突、字段超长、违反 CHECK 约束),只要没 COMMIT,整个事务自动标记为需回滚
  • 常见坑:INSERT IGNOREON DUPLICATE KEY UPDATE 看似“容错”,但它们属于单条语句级处理,不改变事务整体原子性逻辑;真要保原子,得靠外层事务 + 异常捕获
  • 注意:只有 InnoDB 支持完整原子性;MyISAM 不写 undo logROLLBACK 无效

一致性(Consistency):不是数据库自己“觉得一致”,而是你定义的规则必须被强制执行

一致性不是事务“带来”的,而是事务 + 约束 + 触发器 + 应用逻辑共同守住的红线。事务只是那个“守门人”:它确保约束检查发生在事务提交前,且失败即回滚。

  • 典型体现:forEIGN KEY 级联、CHECK(balance >= 0)、唯一索引冲突、触发器抛异常——这些都会让 COMMIT 失败
  • 容易忽略的点:一致性是**业务语义层面**的。比如银行总余额不变,这不是数据库自动保证的,而是靠你在事务里显式校验(如 select SUM(balance) 前后比对)或靠应用逻辑兜底
  • SET FOREIGN_KEY_CHECKS = 0 会绕过外键检查,等于主动放弃一部分一致性保障,上线前务必确认是否真需要

隔离性(Isolation):并发时别互相“串味”,但 MySQL 默认不完全隔离

InnoDB 默认隔离级别是 REPEATABLE READ,但它**不等于**串行执行。幻读(Phantom Read)在当前读(SELECT ... FOR UPDATE)下仍可能发生,只是快照读(普通 SELECT)被 MVCC 隐藏了。

  • 四个级别差异关键在“读可见性”:READ UNCOMMITTED 可见未提交修改(脏读);READ COMMITTED 每次 SELECT 都读最新已提交版本(不可重复读);REPEATABLE READ 事务内所有快照读都基于首次读的时间点;SERIALIZABLE 加范围锁,彻底串行
  • 实战建议:高并发写场景慎用 SERIALIZABLE,性能损耗大;REPEATABLE READ 下若需防幻读,必须显式加 SELECT ... FOR UPDATE 或用 INSERT ... ON DUPLICATE KEY UPDATE 替代“先查再插”
  • 一个经典陷阱:UPDATE t SET x = x + 1 WHERE id = 1READ COMMITTEDREPEATABLE READ 下行为一致,但 UPDATE ... WHERE name = 'xxx'(无索引)可能锁全表,导致严重阻塞

持久性(Durability):提交即落地,断电也不能丢

一旦 COMMIT 返回成功,数据就算服务器立刻断电、进程崩溃,重启后也必须可恢复——这靠的是 redo log 刷盘机制,不是直接写数据文件。

  • innodb_flush_log_at_trx_commit 是核心开关:1(默认)= 每次提交都刷盘,最安全;0= 每秒刷一次,崩溃最多丢 1 秒事务;2= 写 OS 缓存但不强制刷盘,依赖 OS 稳定性
  • 别被“磁盘写入”误导:redo log 是顺序 I/O,远快于随机写数据页;所以即使 sync_binlog=1 开启,只要 innodb_flush_log_at_trx_commit=1,持久性就有保障
  • 真实风险点:某些云厂商 RDS 默认调低该参数以换性能,或使用机械盘 + 高并发写导致 fsync 成瓶颈,此时 COMMIT 延迟飙升,应用可能超时误判失败

ACID 不是抽象概念,每个字母背后都是日志策略、锁机制、约束检查和刷盘控制的具体实现。真正踩过 undo log 被提前 purge 导致回滚失败、redo log 空间满引发 hang、或者 REPEATABLE READ 下幻读引发重复插入的坑,才会明白——事务的“可靠”,从来不是开个 BEGIN 就自动附送的。

text=ZqhQzanResources