如何决策使用数据库事务
总结
当事情需要「多步写,要么全成要么全不成」时,就该上事务。
读多写少、单条写、失败可重试且允许中间态时,通常不必。
「加了事务更安心」不是充分理由——长事务会拖锁、拉高冲突。
优先开事务的信号
1. 一次业务对应多条写
典型形态:A 表插一行 + B 表插/改一行,中间失败不能留下半成品。
| 例子 | 为何要事务 |
|---|---|
| 建队 + 写入队长成员 | 不能只有队伍没有队长关系 |
| 扣库存 + 写订单行 | 不能只扣库存不成单 |
| 软删主实体 + 软删全部关联 | 不能主没了明细还在(或反过来) |
| 改负责人 + 原负责人退出关联 | 两步必须同成同败 |
判定: 若只成功一半,数据是否语义错误?会 → 开事务。
2. 先读后写,且读结果决定写什么(check-then-act)
「查人数 → 未满 → 插入」「查是否成员 → 再退出」在并发下会脏。
| 手段 | 作用 |
|---|---|
| 事务 | 把读和写放进同一边界 |
| 行锁 / 条件更新 / 唯一约束 | 防止别人插队改掉你的决策依据 |
常见组合:事务内 SELECT … FOR UPDATE 关键再按快照决策并写入。
判定: 并发下「我看到的状态」和「我写的时候」可能不一致 → 事务,高并发再加锁或约束。