常见的幂等方案

1. 过滤-去重型(显式挡回重复包)

思路:在业务逻辑之前,先检查"这条请求 / 这条消息是不是第一次见到"。

常见实现

• 数据库唯一索引:INSERT ... ON CONFLICT DO NOTHING

• 去重表 / Redis SET:SADD msgId 看返回值 0/1

• 带 TTL 的布隆过滤器:高 QPS 场景减小内存

优点

• 对已有系统侵入小,只要给消息加 msgId

• 过滤失败后可以"啥也不做"直接 ACK,不会二次执行。

缺点

• 需要额外存储去重键,热点写压力大。

• 强制把"是否重复"与"业务逻辑"分离,代码路径分叉。

• 时间窗口过长会造成键无限增长;过短又可能误判"新老交叉"。

适用

支付、扣款、库存扣减等"不能多扣一分钱/一件货"的硬幂等场景。


2. 状态幂等型(让同一操作幂次方 = 1)

思路:业务本身就是一棵状态机,外部多发同一个动作不再产生新副作用。

实现方式

• 不可变资源:PUT /users/42/address 多次覆盖写,最终状态一致。

• CAS / 乐观锁:只在 version=N 时成功;失败说明已经处理过。

• 状态字段:订单 status = PAID 再收到支付回调直接忽略。

优点

• 内部数据结构最简,复用现成行记录。

• 不依赖额外键值表,天然水平扩展。

• 重放/回溯也安全。

缺点

• 并非所有业务都能"覆盖写"------扣减库存、累计积分就不是幂等操作。

• 状态设计稍有不慎会出现"订单半付款"之类边界态。

适用

资源更新(配置中心、用户资料)、软删除标记、流式统计覆盖写。

怎样选

  1. 一次性副作用(扣钱 / 发货) → 过滤-去重 +/or 事务-原子
  2. 状态覆盖(用户资料) → 状态幂等

相关推荐
易安说AI3 小时前
Claude Opus 4.6 凌晨发布,我体验了一整晚,说说真实感受。
后端
易安说AI3 小时前
Ralph Loop 让Claude无止尽干活的牛马...
前端·后端
易安说AI3 小时前
用 Claude Code 远程分析生产日志,追踪 Claude Max 账户被封原因
后端
颜酱5 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
Coder_Boy_7 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
掘金者阿豪8 小时前
关系数据库迁移的“暗礁”:金仓数据库如何规避数据完整性与一致性风险
后端
ServBay8 小时前
一个下午,一台电脑,终结你 90% 的 Symfony 重复劳动
后端·php·symfony
sino爱学习8 小时前
高性能线程池实践:Dubbo EagerThreadPool 设计与应用
java·后端
颜酱9 小时前
从二叉树到衍生结构:5种高频树结构原理+解析
javascript·后端·算法
掘金者阿豪9 小时前
UUID的隐形成本:一个让数据库“慢下来”的陷阱
后端