标准答案

  1. 为业务事实设计唯一键,例如外部支付流水、用户加活动、订单请求号,并让数据库唯一约束成为最后一道重复创建防线。
  2. 库存扣减、余额变更和状态迁移应使用条件更新、乐观版本号或事务锁定,确保只有满足当前状态的请求可以提交。
  3. 重复请求通过幂等键返回已有结果,避免同一用户动作在并发窗口内执行多次。
  4. 跨服务副作用需要保存状态和外部标识,并用消息去重、对账或补偿处理至少一次投递和不确定回调。
  5. 分布式锁只适合缩小竞争窗口;锁超时、进程崩溃、时钟问题和锁服务故障都要求底层仍然可正确拒绝重复写入。

题目解析

并发问题的根源是多个请求都在旧状态上判断“可以执行”。正确方案要把判断和更新合并为不可分割的持久化操作。

不同业务可接受的重复代价不同。展示类任务可容忍最终去重,扣款和权益发放需要更严格的同步约束和审计。

常见误区

  • 先查询是否存在、再插入,却没有唯一约束或事务保护。
  • 认为加了 Redis 锁就不需要处理锁失效和数据库竞争。
  • 只处理同步重复提交,忽略消息重复、回调重放和人工补偿。

作者信息