不过我可以猜测一下,原因就在于gorm.Expr中,decimal调用的+ 的实现,绝对就不是decimal.Decimal自带的那个Add方法实现。可能跟SQL的实现有关,MySQL的概率更大些,Gorm本身有问题的概率小一些。因为我记得SQL Update语句就是可以 Update var = var + XX 这样的表达。看来以后要有个最佳实践,就是凡是涉及数据库中字段的一些计算,最好放在业务侧处理,不要用任何SQL提供的这些操作。当然哈,这里不包括SQL 提供的 COUNT SUM什么的。
最近在做一个金融相关账务的后台业务,主要是监听链上的合约emit出的Event,把Event存储库的表中,golang用的是Gorm来访问MySQL。但是发现用以下Gorm Update一个字段的时候,在及少数情况下,小数点会计算错误, 其中 Gorm的结构对象的两个字段是用decimal.Decimal来存储的金额,当然decimal。Decimal就是可以用来做账的。
如果是一下更新Balance Available Balance Frozen的金额,在极端情况下会有错误,比如计算
1 - 0.7
的时候,会计算成0.30000000000000004
, 我不知道在gorm.Expr里面发生了什么,或者是MySQL对decimal.Decimal支持的问题,版本原因,反正是错误了然后修改成以下代码,就不会错误了,就是把decimal.Decimal的计算,放到gorm.Expr外面来,计算完再更新进去,我写的单元测试就过了。也就是正确了,懒得深究就为什么了,不知道是gorm还是MySQL的原因,因为我本地的MySQL是5.x。第一次做金融账务相关的业务,也算是第一次真正用golang写后端代码。坑还是不少的。我以下面的写法应该就绕过这个坑了,也不需要管到底是Gorm的问题还是MySQL的问题了。
以上代码,在单元测试中,就把
1 - 0.7
,计算成0.3
了不过我可以猜测一下,原因就在于
gorm.Expr
中,decimal调用的+
的实现,绝对就不是decimal.Decimal
自带的那个Add
方法实现。可能跟SQL的实现有关,MySQL的概率更大些,Gorm本身有问题的概率小一些。因为我记得SQL Update语句就是可以 Update var = var + XX 这样的表达。看来以后要有个最佳实践,就是凡是涉及数据库中字段的一些计算,最好放在业务侧处理,不要用任何SQL提供的这些操作。当然哈,这里不包括SQL 提供的 COUNT SUM什么的。