电话
400 9058 355
ACID 四特性需协同实现:原子性靠 undo log 回滚,一致性依赖约束与事务配合,隔离性由 MVCC 和锁机制保障,持久性通过 redo log 刷盘确保;必须正确配置引擎、参数、约束及事务控制逻辑。
原子性不是“尽量全做”,而是“要么全做,要么全不做”。MySQL 用 undo log 实现它——事务执行中每改一行,都先记下“怎么 undo”;一旦中途出错(比如 UPDATE 失败、连接断开、服务器宕机),InnoDB 就靠这些日志把已做的修改全部抹掉,退回到事务开始前的状态。
START TRANSACTION 后只执行了扣款 SQL,没来得及加款就崩溃,结果钱没了但对方没收到 → 原子性被破坏(实际不会发生,因为 InnoDB 自动回滚)BEGIN / COMMIT / ROLLBACK 要成对出现,且确保 rollback
DECLARE EXIT HANDLER FOR SQLEXCEPTION)UPDATE a; UPDATE b; 看似一组操作,实则无法回滚前者 → 务必先 SET autocommit = 0 或显式 START TRANSACTION
一致性不是 MySQL 自己能单方面实现的特性,它是原子性、隔离性、持久性 + 你写的约束共同作用的结果。比如你建表时加了 CHECK(balance >= 0),又在事务里做转账,那“总余额不变”“余额不为负”这些规则,才可能被守住。
CHECK 约束或外键;否则并发请求下,应用层判断“余额够”和执行“扣款”之间存在时间窗口,可能超卖CHECK 约束在 MySQL 8.0.16+ 才真正生效(旧版本只是语法忽略),务必确认版本;外键会带来额外锁开销,高并发写入时需权衡隔离性解决的是“多个事务同时跑,彼此看到什么”的问题。MySQL 默认用 REPEATABLE READ(通过 MVCC + next-key lock 实现),它能防止不可重复读,但不防幻读;而 READ COMMITTED 只保证读到已提交数据,每次 SELECT 都可能看到新提交的行。
REPEATABLE READ 即可;但如果你做实时报表、资金对账等强一致性读,考虑加 SELECT ... FOR UPDATE 或临时切到 SERIALIZABLE(代价是并发大幅下降)REPEATABLE READ 下,UPDATE 语句仍可能触发 gap lock,导致莫名其妙的锁等待;用 SELECT * FROM information_schema.INNODB_TRX 查当前事务,比猜更靠谱持久性靠 redo log 保证:事务 commit 时,MySQL 先把变更写进 redo log(顺序 IO,快),再异步刷盘到数据文件。只要 redo log 写成功,即使断电,重启后也能恢复。
innodb_flush_log_at_trx_commit 是关键开关:设为 1(默认)最安全,每次 commit 都刷盘;设为 0 或 2 会提升性能,但有丢事务风险(最多丢 1 秒数据)innodb_flush_log_at_trx_commit=1,如果磁盘本身开了 write cache 且没配电池/电容,断电仍可能丢 log → 硬件层也要配合MySQL 的 ACID 不是黑盒承诺,而是由你选的引擎(必须是 InnoDB)、写的 SQL、设的参数、加的约束,一层层搭出来的保障。最常出问题的地方,往往不在“不懂 ACID”,而在“以为开启了事务就万事大吉”,却忘了关 autocommit、漏了约束、压根没查过当前隔离级别。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...