标准答案

  1. UPSERT 把插入与冲突后的更新放在一个原子语句中,适合确定性地写入某个唯一键对应的最新状态。
  2. 应明确冲突时是覆盖、累加、保持原值、更新时间,还是拒绝;不同字段不能默认采用同一策略。
  3. 订单号、支付流水、用户注册等冲突通常有业务语义,应先判断是幂等重试、重复请求还是安全风险。
  4. UPSERT 仍需考虑并发更新的版本、触发器、副作用和受影响行数,不能只看语句成功。
  5. 对导入和同步任务要记录来源、批次和变更证据,便于回滚与排查覆盖范围。

题目解析

UPSERT 的吸引力在于减少先查后写的竞争窗口,但它可能把数据质量问题吞掉。例如两个不同用户争夺同一唯一邮箱,如果冲突后直接更新,可能造成账号归属被错误改写。

正确使用方式是把可合并的事实设计得足够明确,例如某个外部资源的最后同步版本;对不可合并的业务命令,则应让冲突显式失败并进入审核或补偿路径。

常见误区

  • 所有唯一冲突都用 UPSERT 覆盖,导致重复支付或账号冒用没有告警。
  • 忽略并发写入中的字段覆盖顺序,较旧的同步数据反而覆盖较新的状态。

作者信息