防订单反复提交战略办法
背景
在业务开发中,我们常会面临防止反复恳求的问题。当效劳端关于恳求的响应触及数据的修改,或状态的变动时,大概会造成极大的危害。反复恳求的后果在交易系统、售后维权,乃至支付系统中特别严峻。
前台操纵的颤动,快速操纵,网络通讯或者后端响应慢,都会增添后端反复处置的概率。前台操纵去颤动和防快速操纵的办法,我们第一会想到在前端做一层操纵。当前端触发操纵时,或弹出确定界面,或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多种材料选中了钨丝创造了灯泡,实践出真知。碰到问题,和问题斗争,最后解决问题是一个最大晋升自我的历程,不单加宽本人的知识广度,愈加深了本人的技艺深度。到达目标之后的成就感更是不问可知。
以上就是防订单反复提交战略办法的具体内容,更多请关注百分百源码网其它相关文章!