11

RedisTemplate:我不背锅,是你用错了

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzIwMDY0Nzk2Mw%3D%3D&%3Bmid=2650321153&%3Bidx=1&%3Bsn=8059807dbf1660cb13ef6288c44c7b14
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

今天分享一个 RedisTemplate 的问题,感兴趣的可以继续看下去了,不感兴趣的继续撩妹去吧!

如下图:一位朋友给了我一个报错的图片,为啥为啥取不到值?

NfUfeqU.jpg!web

我也有点懵,第一反应就是 RedisTemplate 和 StringRedisTemplate 会不会用的两个不同的 Connection,导致相同的 Key 一个能查到,一个不能查到。

经过反复确认,Connection 没问题,是同一个,还是那句话: 每个奇怪问题的背后一定有故事。

只能调试源码了呗,还能怎么办。最后在 redis.clients.jedis.BinaryJedis#hget 中发现了问题,就是 Redis 压根就没有返回数据。

现在的问题就剩下为什么 StringRedisTemplate 的查询可以返回数据,RedisTemplate 的查询却不能返回数据?

我们来屡一下 StringRedisTemplate 和 RedisTemplate 的关系,StringRedisTemplate 继承了 RedisTemplate,是专门用于字符串操作。

RedisTemplate 一般用于比较复杂的对象操作,区别就在于序列化的不同。

于是我用 redis 客户端查看了存储的数据格式,发现这个 Hash 的格式是字符串。

jMrmMrI.png!web

这也就是为什么用 StringRedisTemplate 可以获取到,估计存储的时候就是用的 StringRedisTemplate。

RedisTemplate 默认的序列化方式是 JDK 序列化,格式不对。

于是查看了 RedisTemplate 的构造方式,发现就是序列化方式不一致。

ry67Rby.png!web

于是将 jdkSerializationRedisSerializer 改成了 stringSerializer。重新跑了一遍测试还是不行。于是我看了下 RedisTemplate 对象的信息,如下:

muimmy2.jpg!web

valueSerializer 是改过来了,但是 hash 有专门的序列化,还是 JDK。

那就全部改成一样的吧,如下:

iiyY73N.png!web

然后就能获取到了,个人感觉这个还是一个使用的问题,可能大家都以为这 2 个 RedisTemplate 是一样的,没什么差别,所以才导致了本文出现的问题。

如果你够细心,其实看下源码就知道这 2 个类的区别了。

7NfY7jM.png!web

StringRedisTemplate 构建的时候默认设置了所有的序列化方式为 String,也就是说 StringRedisTemplate 的数据格式都是 String。

RedisTemplate 没有设置的话就都是 JDK。

3I7f6ja.jpg!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK