云霞资讯网

浅析京东外卖惊天bug:为何买100张券,全额退款,但还有99张可用?

事件经过12月7日晚,京东外卖爆出一个P0级bug:买100张9.9元的瑞幸劵,申请全额退款,钱全退了,但劵实际只退1张

事件经过

12月7日晚,京东外卖爆出一个P0级bug:买100张9.9元的瑞幸劵,申请全额退款,钱全退了,但劵实际只退1张,剩下99张还可以继续用。不少用户都薅到了羊毛,咖啡喝到吐.... 12月8日晚京东外卖发文表示平台承担商家全部损失。

平台愿意承担全部损失,也是很良心了,但这个bug是个低级错误,出现在京东这样体量的系统里让我感到不可思议,作为一个开发者,我忍不住分析该bug出现的原因。

原因推测

先简短分析一下这个退款逻辑:用户提交退款申请—后端根据订单号找到券码—然后一条SQL把券改成失效状态。

根据这个业务逻辑我高度怀疑是后端将劵改成失效状态的那条SQL语句加了limit 1,这样无论这个订单有多少张券,退款时都只会把第一条匹配的券标记为已退款,而其他劵依然可以正常使用。

为什么开发者要加limit 1?

这是一个以求稳妥以及高性能的开发习惯,属于正常操作,但是不符合这个业务场景。

这里会出现

limit 1

有两个原因:

开发者陷入了常见的思维陷阱,常见的退款业务只要修改一个订单状态,未考虑到一个订单可能有多张券

代码复用埋雷,这个退款业务的代码可能是从其他实物订单退款业务从复制过来,没有根据券类的特性进行调整

当然原因可能性很多,这次分析不一定准确,只是根据个人开发经验,这极有可能是

SQL语句错误

导致。具体的原因,不一定准,但从大方向看这肯定是后端的问题,毕竟前端闯不出什么大祸,而这口锅估计得测试背,这么常见的场景都没有测试出来。

由此bug得出的启发:作为开发者,一定要深刻了解业务!懂产品,掌握每一个功能之间的依赖,编写每一行代码都要考虑到其对产品业务的影响。