Redis solves Hincrbyfloat precision loss problem

When using redis to cache amount-related data, in order to ensure the atomicity of the operation, hincrByFloat is usually used to operate. HincrByFloat alone sometimes has the problem of loss of precision. Lua scripts can be used to deal with it, which can ensure both atomicity and precision. not lost
insert image description here

@Test
    public void lua() {
    
    
        String key = "api_sdk_entity:quota_cont:ping001";
        String filed ="sumQuota";
        BigDecimal price = new BigDecimal("100.01");
        List<String> keys = new ArrayList<String>();
        keys.add(key);
        List<String> args = new ArrayList<String>();
        args.add(filed);
        args.add(price.toPlainString());
        System.out.println("======1======"+jcRedisCache.hget(key,filed));
        //--创建val变量并查询hash的数据
        String script ="local val = redis.call('hGet',KEYS[1],ARGV[1]);" +
                //--创建inc_val变量此值就是自增后的值
                "local inc_val;" +
                //--判断val是否存在,存在则增加值,不存在则直接是传过来的值,此处要注意val的redis返回值如果不存在key返回的是nil但是转成lua的结果是 false
                "if val ~=false then " +
                    "inc_val =  tostring(val + ARGV[2]) " +
                "else " +
                    "inc_val =  tostring(ARGV[2])  " +
                "end;" +
                //--操作redis重新赋值
                "local res =redis.call('hSet',KEYS[1],ARGV[1],inc_val);" +
                "if res >= 0 then " +
                    "return inc_val " +
                "else " +
                    "return res " +
                "end;";
        jcRedisCache.commond(script,keys,args);
        System.out.println("======2======"+jcRedisCache.hget(key,filed));
    }
======
 
  @Override
    public String commond(String script,List<String> keys,List<String> args) {
    
    
        String sha = client.scriptLoad(script);
        client.evalsha(sha,keys, args);
        return null;
    }

Guess you like

Origin blog.csdn.net/wenwang3000/article/details/127159061