生产上一个项目,用户提交订单,因为涉及多个接口的调用,所以响应时间肯定超过10秒。因为在数据库对订单编号做了唯一索引,结果发现大量的重复订单插入失败。开始以为是前端没有控制好,造成用户重复点击提交,做了TOKEN这些机制后,仍然发现故障存在。最终多方测试,发现只要是在手机微信端,安卓下,提交订单10秒没有返回,就会有一条提交补上来,数据完全一样。
网上查询资料,从16年就有人发现此问题了。。。。。。。。原因就是默认情况下,请求是从 浏览器-》微信服务器-》网站 这一条线走,但是当这次请求10秒内没有响应时,微信就丢弃此次请求,马上把同样的数据,再走 浏览器-》网站 这条线走。所以我们才会发现有两次同样的请求。
如果只是普通的获取数据这些倒还好,不过就是相当于刷新了一次,但用于数据提交时,就是坑了,巨坑啊。MMP的。
我们的处理方案:
提交进入时,就以订单号为KEY,查询REDIS或是缓存,此订单号是否处于处理中,
如果没有,就将此KEY存入,状态为处理中,然后开户PHP的 ignore_user_abort(true);(防止第一次链接被断开,PHP停止执行),继续执行代码, 执行结束时,将正常的返回数据结果存入REDIS或是缓存的KEY中。
如果查询到此订单在处理中,就一直等待、查询REDIS或缓存中的处理状态,超时则返回错误,查询到处理结果,就取出结果返回。
终于恢复清清净了。。。。。。。