事务基础
- InnoDB 默认开启自动提交(Autocommit=1),单条语句自动提交
- 多条语句需要显式事务块,确保要么全部成功要么全部回滚
- 建议在应用层使用连接池,并在每次请求结束前明确
COMMIT/ROLLBACK
ACID 与隔离级别
- READ UNCOMMITTED:可能脏读(不推荐)
- READ COMMITTED:常见于其他数据库
- REPEATABLE READ(默认):快照读,防止不可重复读
- SERIALIZABLE:最强隔离,但并发差
MySQL 的 REPEATABLE READ 通过 MVCC + 间隙锁规避幻读,对比 Oracle/SQL Server 的 READ COMMITTED 需特别留意行为差异。
一致性读与当前读
- 一致性读(Consistent Read):普通
SELECT在事务开始时创建快照,不会加锁 - 当前读(Current Read):
SELECT ... FOR UPDATE/LOCK IN SHARE MODE、UPDATE/DELETE,会获取行锁
锁类型(InnoDB)
- 行锁:记录锁(Record Lock)、间隙锁(Gap Lock)、临键锁(Next-Key Lock)
- 表锁:
LOCK TABLES或 DDL 导致的隐式表锁 - 共享锁(S)与排他锁(X);
SELECT ... FOR UPDATE、LOCK IN SHARE MODE
死锁与排查
症状:ERROR 1213 (40001): Deadlock found ... 或 Lock wait timeout exceeded。
sys schema 更易读:
幻读与间隙锁
在 REPEATABLE READ 下,范围更新可能触发间隙锁,阻止范围内的插入从而避免幻读。需要注意锁竞争风险。锁等待监控
SHOW PROCESSLIST:查看当前语句与状态performance_schema.events_statements_current:捕获正在执行的语句innodb_status_output_locks = ON(动态变量)可将锁信息写入错误日志
最佳实践
- 保持 SQL 顺序一致(如总是按
orders→order_items更新) - 减少范围更新,优先精准匹配;必要时拆批
- 使用合适索引缩小锁范围
- 对长期运行任务(报表、导出)使用一致性读或在从库执行
- 对于热点写操作,可引入队列/异步处理或乐观锁(版本号)