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 mapCache = redissonClient.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 map = redisson.getMapCache("testMap", StringCodec.INSTANCE);
map.put("test", 1L);
map.addAndGet("test", 1L);

or

RMapCache map = redisson.getMapCache("testMap", TypedJsonJacksonCodec.INSTANCE);
map.put("test", 1);
map.addAndGet("test", 1);

建议根据value类型使用编解码器,如int类型的计数器使用 IntegerCodec.INSTANCE (String转Integer)
RMapCache mapCache = redissonClient.getMapCache("key", IntegerCodec.INSTANCE);
String item = channel + "-" + xxx;
mapCache.putIfAbsent(item, 1, 1, TimeUnit.DAYS);
Integer pv = mapCache.addAndGet(item, 1);

你可能感兴趣的:(bug,redis,redis,数据库,缓存,redisson)