先简单描述下背景。我们的项目是商家发布订单,可以对订单进行加减量,用户以任务为单位做商家发布的订单,每一个任务有各种状态,不同状态会有对订单加减量的操作,比如用户超时未提交会有脚本自动返还扣的量。
我们有一个脚本每天都会对一下订单的消耗各数据是否一致,就是订单支付的总额与订单的消耗、余量的一个对比。有一天报警了一个订单数据不一致的情况,我排查了一下商家的行为,存在大量的加一个量的情况,我以为是这里出了问题,便以此为目标去寻找证据,最终没找到,商家加减量的代码逻辑并没有看到漏洞。不过排查的过程中得到了一个结论——商家的余量比实际支付的多了一个。于是我们手动执行 sql 给这个订单减了一个量,这个问题就暂时搁置了。
前两天又有订单出现了这个问题,我这次换了个思路排查了一下,确定了出现这个问题的原因。由于上次已经确定了不是商家加减量那里的问题,这次就先看了下订单操作余量的代码逻辑(就一处入口,各处调用),以及调用这块逻辑的地方。手动操作的地方是用户开始、放弃任务及商家审核任务,自动操作的地方是两个定时任务——超时未提交及超时未重提。据此提出了一个可能:手动操作与定时脚本同时操作了同一个任务,导致量差了。最终也确实定位了是这个原因,由于任务超时我们并没有限制不能提交或放弃(定时任务将状态更改后才会限制),导致定时任务执行放弃的时候有可能会多退一个量。
在第一次出现这个问题未定位到原因时,再一次出现时,心里是有点抵触去解决的,可能是因为前一次的失败阴影。不过这都是正常的心理,调整好心态就好了。以我的经验来看,遇到的问题基本上都是可以解决的,就是要反复去面对嘛,失败几次是很正常的。
后来是新写了一个更新订单状态的方法,当状态更新失败后,抛出异常来使事务回滚的方式解决的这个问题。
1 | $this->default_model->pdo->beginTransaction(); |