redis DECRBY报ERR value is not an integer or out of range

32 阅读1分钟

最近项目中有使用到lua脚本使用DECRBY去递减金额,因为计算中的一些不规范使用产生了小数位,导致出现了ERR value is not an integer or out of range,使用的lua脚本如下

            local key = KEYS[1] 
            local decrementValue = tonumber(ARGV[1])
            local newValue = redis.call('DECRBY', key, decrementValue)
     

排查方向

最开始以为是ARGV的值引起来的问题,发现项目中使用了BigDecimal进行金额的处理,但是并没有使用在最后的结果中去掉小数位,以致会出现.00的小数(数据库中的金额是两位小数,但是我们并没有使用小数位,都是整数金额),发现这只是问题的其一。

修改完代码之后,发现写入的key的值是使用jedis.incrByFloat,也会产生小数的问题。

问题处理

  1. redis的DECRBY命令需要严格使用整数类型,.00这种也是不能使用的,如果使用BigDecimal,需要使用setScale(0)去掉小数位
  2. 写入的时候value值也不能带小数,最后我的方案是使用jedis.incrBy方法,然后在对value值进行了longValue()进行处理
  3. 需要注意的是lua脚本中的tonumber只是把传入的字符串转成数字类型,并不会改变小数位