前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何防订单重复提交策略方法

如何防订单重复提交策略方法

原创
作者头像
Tinywan
修改于 2018-09-25 01:57:15
修改于 2018-09-25 01:57:15
2.1K0
举报
文章被收录于专栏:开源技术小栈开源技术小栈

#### [原文链接:https://www.cnblogs.com/jett010/articles/9056567.html](https://www.cnblogs.com/jett010/articles/9056567.html)

### 背景

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

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

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

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

### 尝试

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

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

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

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

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

![](https://img2018.cnblogs.com/blog/1021265/201809/1021265-20180917173747789-386317460.png)

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

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

* I. 每次退款发起申请,读取缓存中是否有以orderId为key的值

* II. 没有,则往缓存中写入以orderId为key的value

* III.有,则说明有该订单的退款正在进行。

* IV. 操作完清缓存,或者缓存存值的时候设置生命周期

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

![](https://img2018.cnblogs.com/blog/1021265/201809/1021265-20180917173805925-1949274645.png)

####(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进来则往表里面插入数据:

> 成功,则可以继续操作(相当于获取锁);

> 失败,则说明有操作在进行。

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

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

![](https://img2018.cnblogs.com/blog/1021265/201809/1021265-20180917173814544-1871115286.png)

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

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

还是以订单退款为例子:

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

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

> 如果=1(获得锁): 可以操作。

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

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

![](https://img2018.cnblogs.com/blog/1021265/201809/1021265-20180917173829338-1797651582.png)

## 总结:

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

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
HTTP协议以及基于UDP实现可靠的协议QUIC
在这段时间内花了两个月重学了一遍数据结构,然后在leetcode上刷了一百多道题。
Liusy
2022/01/11
1.1K0
HTTP协议以及基于UDP实现可靠的协议QUIC
网络协议 12 - HTTP 协议:常用而不简单
    网络协议五层通天路,咱们从物理层、到链路层、网络层、再到传输层,现在又进一步,来到了应用层。这也是我们五层协议里最上面的一层,关于应用层,有太多协议要了解。但要说最有名的,那肯定就是 HTTP 了。
北国风光
2019/04/11
6970
网络协议 12 - HTTP 协议:常用而不简单
网络协议 6 - 路由协议:敢问路在何方?
    前面例子中,我们都是在一个局域网内折腾。今天就让我们扩大范围,在多个局域网甚至到广阔的互联网世界中遨游,看看这中间会发生什么。
北国风光
2019/04/11
7080
网络协议 6 - 路由协议:敢问路在何方?
常用的数据链路层协议_数据链路层和网络层
虽然网络中各个局域网所采用的通信技术可能的不同的,但是IP屏蔽了底层网络的差异,对于网络通信双方的IP层及其往上的协议来说,它们并不需要关心底层具体使用的是哪种局域网技术。
全栈程序员站长
2022/11/01
9190
2021-Java后端工程师面试指南-(计算机网络)
面试指南系列,很多情况下不会去深挖细节,是小六六以被面试者的角色去回顾知识的一种方式,所以我默认大部分的东西,作为面试官的你,肯定是懂的。
用户9927510
2022/07/29
3760
2021-Java后端工程师面试指南-(计算机网络)
网络是如何连接的?网络发展简介(四)
这一过程涉及宽带接入、浏览器、前端技术,DNS,TCP/IP,操作系统,网卡,驱动程序,传输设备,交换机、路由器,服务器等等网络、通信、web相关的几乎所有技术
noteless
2019/02/25
4.1K0
网络是如何连接的?网络发展简介(四)
对线面试官 - 网络经典面试题
派大星:可以通过路由器/网关。网关就是路由器的一种,运作在网络层。通过交换机走以太网协议进行一个传输数据包。如图:
@派大星
2023/09/08
2320
对线面试官 - 网络经典面试题
IP协议(网络)
主机: 配有IP地址, 但是不进行路由控制的设备; 路由器: 即配有IP地址, 又能进行路由控制; 节点: 主机和路由器的统称;
ljw695
2025/01/03
1230
IP协议(网络)
【Linux】数据链路层:以太网协议
1. (1)IP提供了将数据包跨网络发送的能力,这种能力实际上是通过子网划分+目的ip+查询节点的路由表来实现的,但实际上数据包要先能够在局域网内部进行转发到目的主机,只有有了这个能力之后,数据包才能跨过一个个的局域网,最终将数据包发送到目的主机。 所以跨网络传输的本质就是跨无数个局域网内数据包转发的结果,离理解整个数据包在网络中转发的过程,我们只差理解局域网数据包转发这临门一脚了。 (2)而现在最常见的局域网通信技术就是以太网,无线LAN,令牌环网(这三种技术在数据链路层使用的都是MAC地址),早在1970年代IBM公司就发明了局域网通信技术令牌环网,但后来在1980年代,局域网通信技术进入了以太网大潮,原来提供令牌网设备的厂商多数也退出了市场,在目前的局域网种令牌环网早已江河日下,明日黄花了,等到后面进入移动设备时代时,在1990年,国外的一位博士带领自己的团队发明了无线LAN技术,也就是wifi这项技术,实现了与有线网一样快速和稳定的传输,并在1996年在美国申请了无线网技术专利。 今天学习的正是以太网技术。
举杯邀明月
2023/10/17
6530
【Linux】数据链路层:以太网协议
TCP/IP第三层--网络层
1)、主要功能:负责点到点(point-to-point)的传输(这里的“点”指主机或路由器)
黄规速
2022/04/14
1.1K0
TCP/IP第三层--网络层
数据包的奇妙旅程:揭秘网络传输的7个关键步骤
我们前面已经了解到为什么网络需要分层,每一层都有自己的职责。在发送数据包的过程中,这些层扮演着不同的角色。它们的主要任务是将数据包进行层层封装后发送,并在接收端逐层解封装。
努力的小雨
2023/11/24
5480
71张图详解IP 地址、IP 路由、分片和重组、三层转发、ARP、ICMP
这要从 TCP/IP 协议说起,互联网使用的是 TCP/IP 协议,其中 IP 协议又是最重要的协议之一。IP 协议是基于 IP 地址将数据包发送给目的主机,能够让互联网上任何两台主机进行通信。
网络工程师笔记
2021/05/17
1.8K0
71张图详解IP 地址、IP 路由、分片和重组、三层转发、ARP、ICMP
彻底搞懂系列之:ARP协议
地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。地址解析协议是建立在网络中各个主机互相信任的基础上的,局域网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;
网络工程师笔记
2021/05/17
3.5K0
彻底搞懂系列之:ARP协议
既然有了IP地址,为什么还需要MAC地址?两者到底有啥区别,深入分析后终于明白了!
在计算机网络中,IP地址和MAC地址是两个最基本的概念。IP地址在互联网中是用于标识主机的逻辑地址,而MAC地址则是用于标识网卡的物理地址。虽然它们都是用于标识一个设备的地址,但是它们的作用和使用场景是不同的。
网络技术联盟站
2023/05/22
11.5K3
既然有了IP地址,为什么还需要MAC地址?两者到底有啥区别,深入分析后终于明白了!
arp属于tcp/ip协议吗_tcp协议与ip协议的区别
本文主要讲述了ARP的作用、ARP分组格式、ARP高速缓存、免费ARP和代理ARP。
全栈程序员站长
2022/09/20
1.1K0
arp属于tcp/ip协议吗_tcp协议与ip协议的区别
输入网址到回显页面,经历了哪些过程
浏览器第一步工作就是要对输入的URL进行解析,从而确定发送给Web服务器的请求信息。
shysh95
2021/12/27
1.2K0
输入网址到回显页面,经历了哪些过程
数据链路层重点总结
又是新的一年,展望2023年,博主给大家带来了网络中数据链路层的重点总结,附上博主本人的实例,帮助大家更好的理解数据是怎么在网络中传输的。
VIBE
2023/01/04
4910
数据链路层重点总结
计算机网络原理梳理丨清晰认识 TCP/IP 协议
Internet 的核心协议就是 TCP/IP,广泛应用于局域网和广域网,目前已有20+年发展史,是现用国际通行标准。TCP/IP 是个协议族,包含有多种协议,网络模型及分层如图所示
码脑
2019/09/27
1.8K0
计算机网络原理梳理丨清晰认识 TCP/IP 协议
面试官都震惊,你这网络基础可以啊![通俗易懂]
例如:一个学校之间的网络就可以成为局域网,而一个国家,多个国家之间可以称为广域网,覆盖的区域不同
全栈程序员站长
2022/08/03
4540
面试官都震惊,你这网络基础可以啊![通俗易懂]
网络协议 3 - 从物理层到 MAC 层
    在上一篇博文中,我们见证了 IP 地址的诞生,机器一旦有了 IP,就可以在网络的环境里和其他的机器展开沟通了。
北国风光
2019/04/11
1K0
网络协议 3 - 从物理层到 MAC 层
推荐阅读
相关推荐
HTTP协议以及基于UDP实现可靠的协议QUIC
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档