讲师中心 微信公众号
AI工具推荐 视频效率加速

防订单重复提交策略方法

阿宇小哥_5103

阿宇小哥_5103

发布时间:2019-05-14 09:17:27

|

6091人浏览过

|

来源于cnblogs

转载

背景

在业务开发中,我们常会面对防止重复请求的问题。当服务端对于请求的响应涉及数据的修改,或状态的变更时,可能会造成极大的危害。重复请求的后果在交易系统、售后维权,以及支付系统中尤其严重。

前台操作的抖动,快速操作,网络通信或者后端响应慢,都会增加后端重复处理的概率。前台操作去抖动和防快速操作的措施,我们首先会想到在前端做一层控制。当前端触发操作时,或弹出确认界面,或disable入口并倒计时等等,此处不细表。但前端的限制仅能解决少部分问题,且不够彻底,后端自有的防重复处理措施必不可少,义不容辞。

在接口实现中,我们常要求接口要满足幂等性,来保证多次重复请求时只有一次有效。

查询类的接口几乎总是幂等的,但在包含诸如数据插入,多模块数据更新时,达到幂等性会比较难,尤其是高并发时的幂等性要求。比如第三方支付前台回调和后台回调,第三方支付批量回调,慢性能业务逻辑(如用户提交退款申请,商家同意退货/退款等)或慢网络环境时,是重复处理的高发场景。

尝试

这里针对“用户提交退款申请”的例子,说明一下尝试过的防重复处理方法的效果。后端防重复处理的方式,我们先后尝试了三种:

(1)基于DB中退款订单状态的验证

这种方式简单直观,从DB查询出来的退款详情(包括状态)往往还可以用在后续逻辑中,没有花额外的工作专门应对重复请求的问题。

这种查询状态后进行验证的逻辑,从代码上线后就一直存在于所有含状态的业务逻辑处理中,必不可少。但对于防重复处理效果并不好:在前端添加防重复提交前,每周平均在25笔;前端优化后,每周降到7笔。这个数量占总退款申请数的3%%,一个仍然无法接受的比例。

理论上,任意次请求只要在数据状态更新之前都完成了查询操作,则业务逻辑的重复处理就会发生。如下图所示。优化的方向是减少查询到更新之间业务处理时间,可降低空档期的并发影响。极致情况下如果查询和更新变成了原子操作,则就不存在我们当前的问题。

防订单重复提交策略方法

(2)基于缓存数据状态的验证

Redis存储查询轻量快速。在request进来的时候,可以先记录在缓存中。后续进来的request每次进行验证。整个流程处理完成,清除缓存。以退款为例子:

  • I. 每次退款发起申请,读取缓存中是否有以orderId为key的值
  • II. 没有,则往缓存中写入以orderId为key的value
  • III.有,则说明有该订单的退款正在进行。
  • IV. 操作完清缓存,或者缓存存值的时候设置生命周期

与1)的发放相比,数据库换成响应更快的缓存。但是仍然不是原子操作。插入和读取缓存还是有时间间隔。在极致的情况下还是存在重复操作的情况。此方法优化后,每周1笔重复操作。

防订单重复提交策略方法

(3)利用唯一索引机制的验证

需要原子性操作,想到了数据库的唯一索引。新建一个TradeLock表:

CREATE TABLE `TradeLock` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`type` int(11) NOT NULL COMMENT '锁类型',
`lockId` int(11) NOT NULL DEFAULT '0' COMMENT '业务ID',
`status` int(11) NOT NULL DEFAULT '0' COMMENT '锁状态',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='Trade锁机制';

● 每次request进来则往表里面插入数据:

成功,则可以继续操作(相当于获取锁);
失败,则说明有操作在进行。

● 操作完成后,删除此条记录。(相当于释放锁)。

目前已经上线,等待下周的数据统计。

防订单重复提交策略方法

(4)基于缓存的计数器验证

由于数据库的操作比较消耗性能,了解到redis的计数器也是原子性操作。果断采用计数器。既可以提高性能,还不用存储,而且能提升qps的峰值。

还是以订单退款为例子:

● 每次request进来则新建一个以orderId为key的计数器,然后+1。

如果>1(不能获得锁): 说明有操作在进行,删除。
如果=1(获得锁): 可以操作。

● 操作结束(删除锁):删除这个计数器。

要了解计数器,可以参考:http://www.redis.cn/commands/incr.html

防订单重复提交策略方法

总结:

PHP语言自身没有提供进程互斥和锁定机制。因此才有了我们上面的尝试。网上也有文件锁机制,但是考虑到我们的分布式部署,建议还是用缓存。在大并发的情况下,程序各种情况的发生。特别是涉及到金额操作,不能有一分一毫的差距。所以在大并发要互斥的情况下可以考虑3、4两种方案。

爱迪生尝试了1600多种材料选择了钨丝发明了灯泡,实践出真知。遇到问题,和问题斗争,最后解决问题是一个最大提升自我的过程,不但加宽自己的知识广度,更加深了自己的技能深度。达到目标之后的成就感更是不言而喻。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

相关专题

更多
Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

20

2026.09.23

Buffalo框架路由与请求处理实操指南
Buffalo框架路由与请求处理实操指南

本专题讲解Buffalo框架路由与请求处理机制,涵盖路由注册与分组、资源路由、Handler编写规范、Context上下文方法、参数绑定、中间件编写挂载、Session与Cookie读写、Flash消息及错误页面定制方法。

0

2026.09.23

Buffalo框架零基础入门教程
Buffalo框架零基础入门教程

本专题整理Buffalo框架入门内容,涵盖Go环境准备、buffalo CLI安装、新项目生成、目录结构说明、dev热加载启动、数据库连接配置与常见报错排查,帮助新手按约定优于配置的思路跑通第一个Buffalo框架应用。

20

2026.09.23

Conan创建软件包配方指南
Conan创建软件包配方指南

本专题介绍通过conanfile.py创建软件包的方法,讲解包名、版本、依赖和构建设置等基础信息,以及source、build、package、package_info等常用方法的作用及编写思路。

0

2026.09.22

Conan二进制包配置指南
Conan二进制包配置指南

本专题介绍Conan根据操作系统、编译器、架构和构建类型生成二进制包的方法,讲解Profile、Settings、Options及Package ID的作用,帮助管理不同平台和编译环境下的包版本。

20

2026.09.22

Conan私有仓库搭建教程
Conan私有仓库搭建教程

本专题系统的讲解Conan私有仓库的搭建流程,涵盖仓库服务部署、存储目录配置、用户认证、权限划分和远程地址添加,并介绍内部C++依赖包的上传、下载及版本维护方法。

20

2026.09.22

loomy官网入口地址合集
loomy官网入口地址合集

本专题汇总了 Loomy 桌面 AI 助理的官方入口地址合集及使用指南。提供 macOS 与 Windows 客户端下载 。Loomy 是讯飞推出的桌面级 AI 工作搭子,支持文件整理、数据分析、网页操作及通过飞书/钉钉远程操控电脑,助你高效完成本地办公任务 。

20

2026.09.22

NumPy常见函数使用方法
NumPy常见函数使用方法

本专题整理 NumPy 常见函数使用方法相关教程,覆盖函数大全、参数用法、数组运算、统计聚合、排序处理、where 条件筛选、linspace 创建数列等常用场景,帮助读者快速掌握 NumPy 函数调用思路和实际数据处理技巧。

0

2026.09.22

NumPy性能优化版本更新与常见报错排查
NumPy性能优化版本更新与常见报错排查

本专题整理 NumPy 性能优化、版本更新与常见报错排查相关教程,覆盖向量化计算、广播性能、内存布局、NumPy 2.0 升级、版本兼容冲突、安装导入报错、dtype 溢出、矩阵运算异常和 broadcasting 报错修复,帮助读者系统掌握 NumPy 性能调优与问题定位方法。

20

2026.09.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn