MySQL 【事务】

发布时间:2026/7/12 1:29:41

MySQL 【事务】 【MySQL 笔记】事务Transaction详解事务是 MySQL 中保证数据一致性和可靠性的最核心机制尤其在涉及多条 SQL 语句需要“要么全成功、要么全失败”的场景如转账、订单创建扣库存、下单减积分等时几乎是必须使用的。一、事务的四大核心特性ACID特性英文通俗解释MySQL 中的体现方式原子性Atomicity要么全做要么全不做undo log MVCC 回滚一致性Consistency事务前后数据库从一个一致状态到另一个一致状态约束主键、外键、CHECK 业务逻辑 隔离级别隔离性Isolation不同事务之间互不干扰锁 MVCC多版本并发控制持久性Durability事务一旦提交数据永久保存redo log 双写缓冲 binlog取决于刷盘策略一句话总结ACID 让你的转账操作不会出现“钱扣了但没到账”或“别人看到中间状态”的灾难。二、MySQL 事务基本语法-- 方式一显式事务最常用、最清晰STARTTRANSACTION;-- 或 BEGIN;UPDATEaccountsSETbalancebalance-100WHEREid1;UPDATEaccountsSETbalancebalance100WHEREid2;COMMIT;-- 提交成功-- ROLLBACK; -- 回滚失败或手动取消-- 方式二自动提交默认行为SETautocommit1;-- 默认就是 1UPDATE...;-- 每条语句立即提交常用组合写法生产推荐STARTTRANSACTION;-- 核心业务逻辑UPDATEaccount_aSETbalancebalance-500WHEREid1001ANDbalance500;-- 检查是否扣款成功影响行数SETaffectedROW_COUNT();IFaffected0THENROLLBACK;SELECT余额不足ASmsg;ELSEUPDATEaccount_bSETbalancebalance500WHEREid1002;COMMIT;SELECT转账成功ASmsg;ENDIF;三、MySQL 支持的事务隔离级别最重要MySQL InnoDB 默认隔离级别REPEATABLE READ可重复读隔离级别脏读不可重复读幻读MySQL 默认备注 / 实际表现InnoDBREAD UNCOMMITTED有有有否基本没人用能读到未提交的数据READ COMMITTED无有有Oracle 默认每次 SELECT 都读最新提交版本电商常见REPEATABLE READ无无有但 InnoDB 通过间隙锁极大减少MySQL 默认同一事务内多次读相同数据结果一致SERIALIZABLE无无无否最高隔离性能最差几乎所有读写都加锁InnoDB 在 REPEATABLE READ 下的特殊行为非常重要通过MVCC 间隙锁Gap Lock Next-Key Lock在大多数场景下解决了幻读但严格意义上仍然存在幻读可能性只在特定加锁读 插入场景实际生产中REPEATABLE READ已经足够安全性能也最好四、事务常见使用场景 推荐隔离级别业务场景推荐隔离级别为什么是否需要显式事务银行转账、支付扣款REPEATABLE READ防止脏读 不可重复读间隙锁防超卖必须电商下单减库存REPEATABLE READ防止超卖结合 SELECT … FOR UPDATE必须普通查询报表READ COMMITTED追求最新数据接受不可重复读可选高并发日志写入READ COMMITTED性能优先不关心幻读通常不需要数据一致性要求极高SERIALIZABLE几乎杜绝并发问题但并发性能极差必须五、事务相关重要系统变量 查看方式-- 查看当前会话隔离级别SELECTtransaction_isolation;-- 或 tx_isolation旧版-- 查看全局默认隔离级别SELECTglobal.transaction_isolation;-- 修改当前会话隔离级别只影响当前连接SETSESSIONtransaction_isolationREAD-COMMITTED;-- 修改全局默认重启后失效需写配置文件SETGLOBALtransaction_isolationREAD-COMMITTED;六、生产中事务常见坑 最佳实践2026 年视角长事务是最大杀手锁住资源很久避免在事务里做大批量操作、循环查询事务尽量控制在 100ms~几秒内忘记 COMMIT / ROLLBACK连接池环境下会自动回滚但显式写更安全在事务里混用 DDLDDL如 ALTER TABLE会隐式提交当前事务SELECT 不加锁就认为安全普通 SELECT 不加锁 → 快照读SELECT … FOR UPDATE / LOCK IN SHARE MODE → 当前读加锁推荐写法模板转账/扣减库存STARTTRANSACTION;SELECTbalanceFROMaccountsWHEREid1FORUPDATE;-- 行锁-- 业务判断UPDATEaccountsSETbalancebalance-100WHEREid1ANDbalance100;IFROW_COUNT()0THENROLLBACK;ELSEUPDATEaccountsSETbalancebalance100WHEREid2;COMMIT;ENDIF;下一期预告建议MySQL 锁机制详解行锁、表锁、间隙锁、Next-Key Lock、MVCC有哪种事务场景你项目里最常遇到转账、秒杀、下单、批量更新等或者对隔离级别、幻读还有疑问欢迎留言我们可以针对性深入祝大家事务写得稳数据不丢不乱

相关新闻