幂等性

幂等操作重复执行与执行一次的效果相同;HTTP 中 GET、PUT、DELETE 定义为幂等方法,POST 通常不是,因此关键写操作需要额外设计幂等机制。

幂等是什么

幂等操作执行一次与执行多次的效果相同,注意判定依据是“效果”而不是响应码或响应体完全一致。HTTP 里 GET、HEAD、PUT、DELETE 被定义为幂等方法,POST 通常不是,因此支付、下单、回调处理这类关键写操作需要额外设计幂等机制。在网络重试、消息重投、用户重复点击都无法避免的分布式环境里,幂等是让重试机制安全成立的前提。

HTTP 方法属性

方法是否安全是否幂等说明
GET/HEAD是是只读,可缓存可重试
PUT否是整体替换,重复执行结果一致
DELETE否是重复删除语义与删除一次相同
PATCH否视实现合并式补丁幂等,数值累加式补丁不幂等
POST否否需要业务侧幂等键去重

基本信息

幂等键客户端生成的唯一请求标识,服务端据此去重并复现首次结果
状态机用状态约束重复请求:已处理的单据再次收到相同指令直接返回
唯一约束数据库唯一索引兜底,防止并发写入产生重复记录
有效期幂等记录需设定保留时长与清理策略,长期保留会造成存储膨胀
适用对象所有会被重试的写操作,包括对外接口与内部消息消费

典型使用场景

  • 支付下单:客户端超时重试时保证不会生成两笔订单
  • 第三方回调:对方重复推送同一笔结果,处理逻辑只生效一次
  • 消息消费:至少一次投递下,消费端按消息键去重
  • 定时补偿任务:任务重跑不会重复扣减或重复发放
  • 批量导入:断点续传或重复上传同一批数据不产生重复记录
  • 运维脚本:接口重试与手工重放不会放大业务影响

幂等处理要点

幂等处理要点
1. 接收请求,读取幂等键(请求头或业务字段)
2. 尝试插入幂等记录:键唯一索引冲突说明已在处理
3. 命中已有记录且状态为成功 → 直接返回首次结果
4. 未完成 → 返回处理中,由调用方按约定重试
5. 业务处理与幂等记录写入保持在同一事务或补偿范围内
幂等与去重不是同一件事:幂等要求重复执行的结果可复现(含响应内容),去重只保证不产生第二条记录,通常仍不足以保证调用方拿到一致结果。
先加唯一索引就算完成幂等,是常见误解;并发下仍是先写库后判重的话,仍可能出现业务侧重复执行。

易错点

  • 重试机制配合未幂等的接口,产生重复订单、重复扣款等直接资金损失
  • 只加唯一索引不做结果复现,调用方第二次请求收到冲突错误,无法确认是否成功
  • 幂等键由服务端生成而非客户端传入,重试时生成新键,去重完全失效
  • 幂等记录长期不清理,去重表迅速膨胀并拖慢写入
  • 业务处理与幂等记录不在同一事务边界内,中途失败导致状态与实际不一致

数据来源与参考

  • RFC 9110 HTTP Semantics(9.2.2 幂等方法)
  • Chris Richardson《Microservices Patterns》
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌