在做后端开发时,很多人都听过一个词:
接口幂等性(Idempotency)
但真正理解并正确实现幂等性的程序员,其实并不多。
很多系统一旦遇到 重复请求、网络重试、支付回调重复,就容易出现:
- 重复下单
- 重复扣款
- 重复发货
- 数据异常
这些问题本质上都是 接口没有做好幂等性控制。
今天我们就来聊一聊:
接口幂等性到底是什么?以及常见的实现方式。
一、什么是接口幂等性?
简单来说:
无论请求执行多少次,结果都是一样的。
例如:
用户点击“提交订单”按钮。
即使因为网络问题,客户端 连续请求 3 次:
POST /createOrder系统最终也只能生成 一个订单。
这就是接口幂等性。
二、为什么一定要做幂等性?
现实系统中,重复请求是非常常见的:
1 用户重复点击
很多用户会疯狂点击按钮:
提交提交提交如果没有幂等控制:
可能会生成 多个订单。
2 网络超时重试
客户端常见逻辑:
请求超时 → 自动重试如果接口没有幂等性:

系统会重复执行操作。
3 第三方回调重复
例如:
- 支付回调
- 物流回调
很多第三方平台都会 重复发送回调。
如果没有幂等性:
可能会 重复扣款或重复更新状态。
三、最常见的幂等实现方式
下面是实际项目中最常见的几种方案。
方法一:数据库唯一索引(最简单)
这是最常见的方式。
例如:
订单表:
order_nouser_idamount我们可以给 order_no 加唯一索引:
UNIQUE KEY (order_no)客户端每次请求都带一个唯一订单号:
order_no = UUID如果重复请求:
数据库会直接报错:
Duplicate entry优点:
- 实现简单
- 数据库保证一致性
缺点:
- 需要提前生成唯一 ID
方法二:幂等 Token(防重复提交)
这种方式常用于:
表单提交场景
流程:
1 用户进入页面
2 后端生成 token
3 token 存入 Redis
4 提交时携带 token
例如:
POST /submitOrdertoken=abc123服务器逻辑:
1 判断 token 是否存在2 如果存在 → 处理请求3 处理完成 → 删除 token如果再次提交:
token 已不存在直接拒绝请求。
优点:
- 防止用户重复点击
缺点:
- 需要 Redis
方法三:Redis 分布式锁
适用于:
高并发场景
例如:
秒杀系统。
实现思路:
SETNX order:userId如果返回成功:
说明锁获取成功。
执行下单逻辑。
如果失败:
说明请求已经在处理。
优点:
- 适合高并发
缺点:
- 需要注意锁过期时间
方法四:状态机控制
很多大型系统会使用 状态机方式。
例如订单状态:
待支付已支付已发货已完成支付回调逻辑:
if (order.status != 待支付) return只有在 待支付状态 才处理。
这样即使回调多次:
系统也只会执行一次。
优点:
- 非常稳定
缺点:
- 需要良好的状态设计
四、很多程序员容易犯的错误
很多系统只做了 前端防重复提交:
按钮点击后禁用但这是 完全不可靠的。
原因很简单:
用户可以:
- 刷新页面
- 抓包重放请求
- 模拟接口调用
真正的幂等性:
一定要在后端实现。
五、实际项目推荐方案
一般推荐:
组合方案
例如:
唯一订单号 + 数据库唯一索引 + 状态机如果是支付系统:
再加上:
支付流水号唯一这样基本可以避免 99% 的重复请求问题。
结语
接口幂等性其实不是一个复杂技术。
但却是:
高可用系统必须具备的能力。
很多线上事故,本质原因都是:
没有做好幂等控制。
真正成熟的系统,都会在设计阶段就考虑:
- 重试
- 回调重复
- 网络异常
如果你是后端工程师,这个能力非常重要。