生产环境出现一个 bug,数据分析的其中一个结果返回为负数,这个功能主要对店铺的已发货订单做时效分析(总发货时间毫秒数-总审单时间秒数)/(总发货订单数量*1小时的毫秒数)

  • 查看相关代码,使用测试数据 debug 后并没有发现什么问题
new BigDecimal(sendTime).divide(new BigDecimal(1000 * 60 * 60 * sendCount), 2, RoundingMode.HALF_UP)
  • 接着排查,既然结果出现了负数,可能是因为有脏数据存在,查询审单时间大于发货时间的订单
  • 查询为空,说明数据正常,即 sendTime 不是负数,那么就只能是 sendCount 是负数,但是 debug 一切正常
  • 继续测试,点开 BigDecimal 的构造方法,发现它调用的是 BigDecimal(int val) 这个构造方法,判断是数据溢出问题
  • 修改问题代码,显式的类型转换即可,使用 BigDecimal(long val)
new BigDecimal(sendTime).divide(new BigDecimal((long) 1000 * 60 * 60 * sendCount), 2, RoundingMode.HALF_UP)

测试环境显示正常的原因是因为单数太少(Integer.MAX_VALUE/1000/60/60=596),所以不会有数据溢出情况

Q.E.D.


盛年不重来,一日难再晨。