如何保证同一个用户提交的订单不重复?
最近一直都遇到一个很让我郁闷的事情,自己开发的系统上线后一直都会存在个别一两单支付了没有修改订单状态的问题,而且出现问题的订单是在同一秒里重复产生了好几个订单最后给了钱没有修改到订单状态。
问题图:
这一张图中是12号桌用户产生的一个订单,它最后成功的订单是2017092918226这一单是支付成功的,却没有修改为支付成功,其他不成功的,看订单的生成时间竟然都是在同一个时间点相差几秒。不知道为什么都没有去执行修改订单状态。
让我郁闷很久,也是奇怪很久的事情
为什么一晚上90多个订单,就出现1到2单会出现这种情况。因为这家餐饮店是一家新开的店,店里网不是很好,这让我一直怀疑是网出现卡顿所产生的重复提交订单的原因。但是那边一直认为是我们系统的问题,现在一直想用代码解决这个问题,加了好几层逻辑限制都没有办法解决这个问题。所以想求助大神帮忙分析下问题怎么解决。
代码流程:
特别说明:自己和公司的人(100多号人)同时测试这个系统过(操作并没有讲清的情况下测试),都正常。另外也叫过25个人同时下单(操作并没有讲清的情况下测试),10分钟内测试下单300多单,没有一单出错。但是不知道为什么当在店里客户消费时却出现这种问题,因为不知道用户是如何操作的,其次查看流量监控,当时并不是用餐高峰的请求点,还有订单生成时间段里,是几分钟有一单支付成功生成。所以推断不是用餐高峰的同一时段并发导致的重复订单生成,其他桌都可以支付成功,却只是个别桌子出现订单重复生成导致支付后没有支付成功,真的让我很郁闷。
希望大神可以给我诊断下这个问题,小生第一次遇到这种事情,谢谢了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
前端:状态设置,防止重复点击
后端:redis setnx
最后的解决办法是,
前端的按钮需要一点就改变,我用的是替换为另一个没有点击事件的按钮防止再点击。
2.后端限制
匹配查询上一张间隔是否相差15秒内,如果15秒内禁止重复提交订单。有效防止短时间内多单提交。
有没有测兼容性,
回调出问题的话,要弄清楚那个订单,都执行了哪些sql语句,代码在哪里执行突然断了,还有就是微信总共给你发起了几次回调。比如说开
启tp的debug模式。或者mysql写入慢日志,还有就是你可以写个方法,把要调试的内容存文件或数据库,比方说回调开头,存xml,回调执行时间,这些记下来好排查!
1、前端去禁止重复点击。2、后端对业务处理,发现重复的订单,禁止入表
这个问题不要通过纯前端的方式去解决吧!看数据库里面的记录基本都是同时提交的,题主也说公司N多人一次测试也未能重现。
解决方案:让请求“幂等”。 简单来说在付款的页面提前获得一个下单的token,每个token只能提交一次订单,以同样的token创建订单不会成功。
一个按钮就够了
给这个按钮加个disabled属性,然后置个标志位。
当发送请求时,把disabled设置为true,禁止点击付款,等异步结果回来了才能点击。
还有一种情况,当异步结果返回该订单号已存在,则可以跳转个新页面,告诉用户不要再提交了,可以去哪里查看到已提交的订单。
我现在的平台也有此类的问题,一般都是用户点击的时候重复,瞬间的事情,很难鉴定的,我现在用的最简单粗暴,只要提交了,就按钮灰掉或者跳转,不等到服务器给出反馈。希望你有好的方案后能分享下。
支付类的操作不应只是在前端做拦截校验,后台也需要做拦截
提交订单就保存到系统,然后查出订单显示详情,下面显示确认按钮,确认后显示去支付的页面
这样直接从设计角度防止重复提交,就算提交订单那一步重复了,确认的订单绝对是存在的
PS: 不建议直接修改按钮disable状态, 因为有些时候莫名还是能点的。
最好直接显示一个层,禁止事件冒泡, 层遮住整个页面。 和禁用状态一起用更保险
前端payOrder和payMoney的完整函数我没有看到,不知道其中是不是有问题。
看楼主的描述,前端方面我没有发现什么问题。
后端方面,支付完成了没有修改订单的状态,这点肯定是后端代码有问题的。
你微信支付的时候肯定需要传个本地订单号给微信,好像有个字段是attach之类的,可以传本地的订单,支付成功后它会原样返回。
返回后你再去通过这个订单号和对应的支付金额去修改相应的订单的状态,即使短时间内产生了很多订单,订单号也是不一样的;修改订单状态应该是没有问题的。
补充:
重复下单的问题,前端问题没有找到前,可通过后端来控制,每个订单包含的商品编号,数量,下单用户如果一样,且在短时间内,比如2分钟,则可判断为重复下单。