Java教程

生产环境一个订单状态错误的排查与反思

本文主要是介绍生产环境一个订单状态错误的排查与反思,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

  --问题现象--

  生产环境上发现一个奇怪的现象:如果充电用户充入充电金额,金额在充电过程中耗尽,那么订单的状态是A(退款过程中);而如果用户充入充电金额,金额没有在充电过程中耗尽,那么订单的状态是B(订单关闭)。

  这里简单描述一下这个订单状态变化的过程:

  1.用户结束订单时,硬件返回状态,包含耗电量,订单id等;

  2.系统根据用户的计算结果,判断订单时直接关闭(状态B),还是发起退款(状态A);

  3.发起退款时进行计算,并调用支付模块进行退款

  4.退款回调,处理完毕后,订单被置为关闭(状态B)。

-------------------------------------------------------------------------------------------------------------

  --解决过程--

  在现象中,整个退款发起,回调,而后订单被置为关闭的链路应该是正常的。问题可以归咎在金额耗尽,应该设置为(状态B)但是结果却是(状态A)的情况。

  没有什么头绪,去DB中查询到了99%的金额耗尽的订单都被置为了A(退款中),所以很确定这个过程一定是发生在系统结束订单的过程中。于是在日志中寻找了整个结束订单的日志,但没什么思路,日志里的信息并没有什么帮助。

  怀疑订单已经正常的结束,被打上了状态B,但是由于某种原因,很快又被更新成了状态A。

  于是找到系统里,所有更新成状态A的代码位置,打上标记,发布到服务器,看看是否能够印证上述怀疑。但是整个过程中没有发现这个状态本身的更新有什么问题。但在过程中发现了一个细节,订单被设置为退款中A的状态之后,退款却没有真正执行。

  于是想到,是否订单在进入退款计算环节之前和进入之后的计算结果不一致?是不是计算环节有问题?于是将两次计算的结果以及订单的所有字段全部打印出来。再次发到服务器上,并在服务器上查看日志。

  最终发现:在第2步计算的结果始终大于0,所以所有的订单全部都是转换为了状态A,但是进入第3步,校验计算的结果时,发现其实只有部分订单真正地应该退款,所以金额耗尽的那一部分订单就在此停止了,并未回滚,造成订单就此结束,状态错误。为什么2和3结果会错误呢?原因是在2计算完成后,根据硬件返回的状态对订单的字段进行了部分更新,导致2和3的计算依据并不一致。

 -------------------------------------------------------------------------------------------------------------

   --经验总结--

  虽然这个错误看着上文的分析好像很简单,但是在解决的过程中却不是那么显而易见的。所以这里仔细回想整个解决过程,反思为什么会造成这么坎坷的解决过程,争取总结经验,让未来避免或者及时发现这个问题。

  1.最大的问题,还是在于,发起退款函数中的计算校验,在计算出不应该退款时没有返回异常。如果这里返回了异常,回滚了整个过程,那么应该在测试阶段就能够及时发现这个bug,不会拖延到生产环境。要知道异常抛出导致整个订单结束的失败,是很容易让测试人员发现,但这个过程如果错误的完成了,造成数据的不匹配,想发现这个问题其实对测试人员业务水平的考验更大。

  2.函数尽量做到一个函数做一件事,当然这会花费更长的时间,所以怎么保证开发效率的同时也向这个目标靠近是一个平衡术。但这个bug的产生过程中,不同的函数中发生了多次对于订单参数的更新,并进行了save操作,这是不正常的,在编码过程中要避免这种一个连贯的逻辑中多次更新的操作。这不仅降低了代码效率,也容易发生意外情况。在代码的封装过程中,辨别这种情况,并保证一个流程只进行一次实体对象的save操作。

这篇关于生产环境一个订单状态错误的排查与反思的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!