标准答案
- 先区分瞬时竞争与业务冲突,版本失败本身不是一个可以无脑重试的技术异常。
- 可重放、无副作用且冲突概率低的操作,可以限制次数地重新读取最新状态后重试,并记录重试指标。
- 用户编辑的文本、配置或审批结果发生冲突时,应展示最新版本和差异,让用户决定覆盖、合并或放弃。
- 支付、库存、订单状态等有外部副作用的命令不能直接重复执行,应查询幂等记录、状态机和补偿证据。
- 更新语句需要同时条件校验版本和业务状态,返回受影响行数作为成功或冲突的依据。
题目解析
自动重试的前提不是“失败了”,而是重试后的语义仍然正确。比如把计数器加一可以通过原子操作或重读后重试完成;把用户填的表单整体覆盖到新版本则可能覆盖他人的修改。
高价值流程应把版本冲突视为可观测业务事件。若冲突率突然上升,可能是热点对象、错误的读写路径或流程设计问题,而不是简单增加重试次数。
代码示例
版本和状态都放在更新条件中,受影响行数为 0 时不能直接视为普通成功。
sql
UPDATE orders
SET status = 'confirmed', version = version + 1
WHERE id = ?
AND version = ?
AND status = 'pending';常见误区
- 版本冲突后直接再次提交相同旧对象,形成无限重试或覆盖新数据。
- 把受影响行数为 0 一律解释为“记录不存在”,遗漏状态不合法和版本过期。