关于全局BigDecimal序列化引发的惨案
原创2025/1/3大约 2 分钟
关于全局BigDecimal序列化引发的惨案
1、业务背景
现有某电商项目,基于 Spring Cloud Alibaba 微服务架构,用户在商家端核销后会进行分账的动作,具体来讲:brand-web 服务监听到核销事件后,根据一定的规则和条件查询出相应的分账比例,然后将参数以 @RequestBody 对象的形式发起调用底层的订单服务,其中分账比例等参数是 BigDecimal 类型。
2、问题现象
发现测试环境及线上库的部分分账数据,其中手续费为 0,理应不是 0。
3、排查过程
首先查看相应的计算分账金额模块的代码,再比对着数据库中的数据,推测不可能是字段数据为空的原因。
既然不可能为空,那就可能是计算出来就是 0。这几个字段都是 BigDecimal 类型,就在此时,同事也反馈说遇到过在调用微服务接口时 BigDecimal 类型的参数的精度被忽略或者保留了,我恍然大悟,之前加过一个针对 BigDecimal 进行序列化的自定义配置,当时是为了给前端返回数据时都能统一保留两位小数:

4、定位原因

大概率是这个全局序列化配置导致的问题,因为毕竟 Spring Cloud 微服务调用也是通过 HTTP 的方式进行的调用,验证一下,注释了此配置,再次调用,不存在此问题了。
5、解决方案
当初加此配置的目的是为了给前端返回数据的时候统一保留两位小数,为了避免在每个字段上都加上 @JsonSerialize(using = BigDecimalSerializer.class) 的配置,才设置的全局配置,没想到这个懒还是没偷成!
6、总结经验
- 在加全局处理的时候一定要慎重、充分论证!
- 跟钱有关的东西一定要慎重慎重再慎重!!!

