redisson类RMapCache执行addAndGet报错问题解决
报错
ERR Error running script (call to f_xxx): @user_script:1: user_script:1: attempt to perform arithmetic on a nil value . channel: [id: xxx, L:/xxx - R:/xxx] command: (EVAL), params: [local value = redis.call(hget, KEYS[1], ARGV[2]); local expireDate = 92233720368547758; local t = ..., 8, xxx:xxx:pv, redisson__timeout__set:{xxx:xxx:pv}, redisson__idle__set:{xxx:xxx:pv}, redisson_map_cache_created:{xxx:xxx:pv}, redisson_map_cache_updated:{xxx:xxx:pv}, redisson__map_cache__last_access__set:{xxx:xxx:pv}, redisson_map_cache_removed:{xxx:xxx:pv}, {xxx:xxx:pv}:redisson_options, ...]
代码
RMapCache<String, Integer> mapCache = redissonClient.<String, Integer>getMapCache("t:v:pv"); String item = channel + "-" + app; // mapCache.put() 该方法不报错 // 此处报错 mapCache.putIfAbsent(item, 0, 1, TimeUnit.DAYS); // 此处报错 Integer pv = mapCache.addAndGet(item, 1);
说明
RMapCache不指定Codec的情况下默认使用JsonJacksonCodec 代码测试运行中使用 MarshallingCodec 编解码器 RedissonMapCache 类 addAndGetOperationAsync 方法指定了编解码器 StringCodec 所以使用 getMapCache 方法最好指定 StringCodec 编解码器 commandExecutor.evalWriteAsync(name, StringCodec.INSTANCE,XXX) 或者value指定Integer类型使用 TypedJsonJacksonCodec 编解码器
正确使用
The correct setup to use addAndGet should be as follows: RMapCache<String, Long> map = redisson.getMapCache("testMap", StringCodec.INSTANCE); map.put("test", 1L); map.addAndGet("test", 1L); or RMapCache<String, Integer> map = redisson.getMapCache("testMap", TypedJsonJacksonCodec.INSTANCE); map.put("test", 1); map.addAndGet("test", 1); 建议根据value类型使用编解码器,如int类型的计数器使用 IntegerCodec.INSTANCE (String转Integer) RMapCache<String, Integer> mapCache = redissonClient.<String, Integer>getMapCache("key", IntegerCodec.INSTANCE); String item = channel + "-" + xxx; mapCache.putIfAbsent(item, 1, 1, TimeUnit.DAYS); Integer pv = mapCache.addAndGet(item, 1);