事务应在必要时以最小粒度、最短时间、最明确边界使用;避免在事务中执行耗时操作,合理选择隔离级别(如非金融场景用read committed),并善用savepoint实现精细化回滚。

事务不是万能的,也不是越多越好。关键是在数据一致性真正需要保障的环节,用最小粒度、最短时间、最明确边界的方式去使用。
只在必要时开启事务
不是所有写操作都要套事务。比如记录日志、更新统计缓存、发送消息等,本身不要求强一致性,加事务反而增加锁竞争和回滚开销。MySQL 的 autocommit 默认开启,单条 INSERT/UPDATE/DELETE 语句本身就是独立事务;只有当你明确需要“多个语句要么全成功、要么全失败”时,才显式用 BEGIN / START TRANSACTION 包裹。
- 典型场景:用户下单(扣库存 + 插订单 + 扣余额),三步必须原子执行
- 反例场景:后台定时任务批量更新 10 万条状态字段,用一个大事务容易锁表、占满 undo log、拖慢主从同步
控制事务长度:快进快出
事务打开后,MySQL 会一直持有锁(行锁或间隙锁)、维护 undo 日志、占用连接资源。长时间事务是性能杀手,也容易引发死锁和主从延迟。
艺帆网络工作室网站源码,是国庆后新一批新概念的网站源码,采用流行的Html5和JS组合流畅顺滑,界面清晰明朗,适合科技类企业和公司建站使用。如果你是想成为一家独特的设计公司,拥有独特的文化,追求品质,而非数量与规模。 这种坚持一直贯穿于项目运作之中,从品牌建立、形象推广设计到品牌形象管理。那可以考虑使用这款艺帆网络工作室网站源码。 这款源码中服务项目和团队程序需要在_template文件夹下的in
- 避免在事务里做耗时操作:如调用外部 HTTP 接口、生成复杂报表、读取大文件
- 把可并行、无依赖的逻辑移出事务:比如订单创建成功后发短信,应放在 COMMIT 之后异步处理
- 监控 long_trx:通过 information_schema.INNODB_TRX 查看运行超 5 秒的事务,及时告警
合理选择隔离级别,不盲目上 REPEATABLE READ
MySQL 默认 RR 级别能解决脏读、不可重复读,但代价是 Gap Lock 和更多锁冲突。很多业务其实只需要 READ COMMITTED —— 它允许不可重复读,但避免了大部分间隙锁,对高并发更新更友好。
- 金融核心账务类系统:RR 合理,强一致性优先
- 电商商品库存、秒杀、用户行为埋点:RC 更合适,减少锁等待,配合应用层重试即可
- 注意:RC 下 binlog 格式必须为 ROW,否则主从可能不一致
用好 savepoint,精细化回滚
一个事务中某些步骤失败,不一定需要整个回滚。用 SAVEPOINT 可以标记中间状态,按需回退到某一点,保留前面已完成的逻辑。
例如:下单流程中,先校验库存(ok),再生成订单号(ok),但插入订单明细时因格式错误失败。此时用 SAVEPOINT 订单明细前,就能只回滚明细部分,保留订单头信息供重试。
- 语法示例:SAVEPOINT sp1; … INSERT …; IF error THEN ROLLBACK TO sp1;
- 注意:savepoint 不释放锁,只是标记回滚位置;大量嵌套 savepoint 会增加事务管理开销









