RedisTemplate获取由INCR命令执行的值

redisTemplate 直接使用 redisTemplate.boundValueOps("1829273").get() 方法获取 incr 值会报如下异常。
Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?

问题原因:

redisTemplate 对 redis 进行读写操作的时候,需要经过序列化和反序列化,而由命令 incr 执行出的值不能直接被反序列化为字符串。
详细原因:RedisTemplate是使用的JdkSerializationRedisSerializer序列化,序列化后的值包含了对象信息,版本号,类信息等。StringRedisTemplate序列化策略是字符串的值直接转为字节数组

解决办法:

  1. 不要使用 RedisTemplate 使用 StringRedisTemplate 同样的方法能够获取到正确的值。
stringRedisTemplate.boundValueOps("1829273").get();
  1. 使用 redisTemplate.getStringSerializer() 获取字符串序列化器,然后再获取值,便可以正常获取
RedisSerializer stringSerializer = redisTemplate.getStringSerializer();
byte[] serialize = stringSerializer.serialize("1829273");
String deserialize = (String) stringSerializer.deserialize(redisTemplate.getConnectionFactory().getConnection().get(serialize));

  1. 使用 RedisAtomicLong
RedisAtomicLong counter = new RedisAtomicLong("1829273", Objects.requireNonNull(redisTemplate.getConnectionFactory()));
// 直接获取值
long l = counter.get();
// 获取值 并且自增1    获取到的值和存在库中的不一致
long andIncrement = counter.getAndIncrement();

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×