项目场景:

在一次与银行对接过程中,需要将获取的交易流水记录保存到数据库,鉴于有多条记录存在,采用批量插入。交易金额,数据库中用的是decimal(25,2),JavaBean中用的BigDecimal。


问题描述

但插入数据成功之后,通过对数据调查发现,插入的数据并不总是与预期数据一致,有时存在数据精度丢失问题,有时就正常。比如插入的记录中,交易金额有10000、1324234.34、234324234.2,最终插入的数据库中的数据变成了10000.00、1324234.00、234324234.00。

但通过观察日志,插入之前打印的日志中,数据是正确的,但最终落库的数据不对,明显是在插入过程中出现的问题。


原因分析:

经过多次插入试验以及对多次插入的数据的结果对比,发现,插入的数据的精度一致时,最终落库的数据是正常的,插入的数据精度不一致时,会出现与预期数据不符的现象,而且,此时,并非是所有数据都不一样,只是个别数据会有出入。

插入前数据:10000、1324234.34、234324234.2

插入后数据库中数据:10000.00、1324234.00、234324234.00

落库的数据最终是以数据中的最小精度来确定最终所有数据的精度进行存储的,而且,与数据的顺序无关。

插入前数据:10000.23、1324234.58、234324234.34

插入后数据库中数据:10000.23、1324234.58、234324234.34

插入前数据:10000.2、1324234.5、234324234.7

插入后数据库中数据:10000.20、1324234.50、234324234.70

在排查过程中,将SQL语句直接执行的话,也不存在这个精度损失问题,换成MySql数据库,也不存在这个问题。


解决方案:

在插入之前,在Java代码中,对要插入的数据的精度进行统一设置,保持所有数据精度一致,就可以解决这个问题。

record.setHpnAm(new BigDecimal(detail.getHpnAm()).setScale(2, RoundingMode.HALF_UP));

最终,虽然通过试验对比,成功解决了问题,但具体原因尚不明确,并未找到设置最小精度的对方。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐