防重复提交:幂等设计与高并发优化
文章目录
- 防重复提交:幂等设计与高并发优化
-
- 问题从哪来
- 核心思路
- [Redis 怎么做](#Redis 怎么做)
- 为什么还要数据库唯一键
- 落地建议
- 结论
问题从哪来
重复提交一般不是用户故意捣乱,更多是网络抖动、接口超时、前端重试、按钮连点,或者页面刷新导致的。注册、下单、转账、保存表单,这些接口只要不是幂等的,就很容易出重复数据。
核心思路
真正稳的方案通常是三层一起做:
- 前端按钮置灰,减少误触
- 后端接口幂等,防止重复请求
- 数据库唯一约束兜底,防止并发穿透
Redis 怎么做
最常见的是给每次请求生成 requestId,然后用 Redis 的 SETNX 思路做一次性占位。
java
Boolean ok = redisTemplate.opsForValue()
.setIfAbsent("req:" + requestId, "1", Duration.ofSeconds(30));
if (Boolean.FALSE.equals(ok)) {
return Result.fail("请勿重复提交");
}
为什么还要数据库唯一键
因为 Redis 只能挡住大部分重复请求,挡不住所有并发竞态。真正最终兜底的,还是数据库唯一索引。
落地建议
- 业务唯一键一定要清楚,手机号、订单号、请求号别混
- 幂等 key 要带用户维度,避免串号
- 成功结果最好也能缓存一下,重复请求直接返回结果
- 失败和成功要区分处理,别把一次失败误当成功
结论
防重复提交不是一个"加锁"问题,而是一个从接口到数据库的幂等设计问题。