后端接口重复提交怎么办?用幂等键把一次操作做成一次

举报
yd_236134918 发表于 2026/11/05 09:15:33 2026/11/05
【摘要】 重复提交几乎不是用户手抖,而是网络重试、页面重复点击、消息重复投递造成的。同一笔操作被执行两次,后果可能是重复扣款、重复发货、重复建单,所以后端接口要做到:同一个请求,无论来几次,最终效果只发生一次。这就是幂等。最实用的做法是幂等键。客户端为每一次业务操作生成一个唯一键,随请求一起发过来,常见做法是放在请求头 Idempotency-Key 里,键的粒度必须是业务操作本身,比如一笔订单、一张...

重复提交几乎不是用户手抖,而是网络重试、页面重复点击、消息重复投递造成的。同一笔操作被执行两次,后果可能是重复扣款、重复发货、重复建单,所以后端接口要做到:同一个请求,无论来几次,最终效果只发生一次。这就是幂等。

最实用的做法是幂等键。客户端为每一次业务操作生成一个唯一键,随请求一起发过来,常见做法是放在请求头 Idempotency-Key 里,键的粒度必须是业务操作本身,比如一笔订单、一张工单,而不是用户ID加时间戳。服务端收到后先查这个键:如果已经处理过,直接返回第一次的结果,不要报错、不要重新执行;如果没处理过,在同一个事务里把业务操作和幂等记录一起落库,键上建唯一索引,靠数据库唯一约束兜底并发重复。

只靠幂等键还不够,业务本身也要能安全重放。订单、工单这类对象适合用状态机:只有待处理状态才能流转到已处理,已处理状态再收到同一请求就直接返回,不再流转。库存、余额这类数值变更不要用先读后写再覆盖,改用带条件的更新,比如 update stock set stock = stock - 1 where id = ? and stock >= 1,靠影响行数判断是否成功,避免两次扣减。

第三个常见坑是去重表和业务表不在同一个事务里。先写去重记录、后做业务,中间一断电就会出现去重已记、业务没做,下次重试被误判为已处理;先做业务、后写去重,重复请求又会穿透。所以幂等记录、业务写操作、状态变更要放在同一个本地事务里,跨服务时再用事务消息或最终一致的补偿来收尾,不要把幂等做成事后对账。

落地前按这张清单自查一遍:幂等键是不是业务级唯一、过期时间是不是合理(太短会误重放,太长会占着键不放)、重复请求返回的是第一次的结果还是错误、并发重复有没有唯一索引兜底、失败重试会不会把半成品当成已完成。把这五项做对,重复提交就从线上事故变成一句可以安全重试的普通请求。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。