zoukankan      html  css  js  c++  java
  • redisTemplate写哈希表遇到的坑

    本文系原创,如有转载,请注明出处 

    在使用spring的redisTemplate进行redis哈希表的相关操作时,遇到了下面比较奇怪的情况:

    • 1.删掉哈希表所属的key之后,重新get这个key的值,得到的不是null,而是一个空的map
    • 2.直接get一个不存在的key,得到的不是null,而是一个空的map
    • 3.set进去一个null值值后,重新set一个非空的map,这个key对应的仍然是一个null

    那先看一下我写的setHash和getHashTable这两个方法:

    1.首先setHashTable

    public void setHashTable(final String key, Map<String, String> value) {
            Object res = redisTemplate.execute(new SessionCallback() {
                @Override
                public Object execute(RedisOperations operations) throws DataAccessException {
                    operations.multi();
                    operations.delete(generateKey(key));
                    operations.opsForHash().putAll(generateKey(key), value);
                    Object val = operations.exec();
                    return val;
                }
            });
            if (res == null) {
                log.error("redis transaction fail, key is : {}", key);
                throw new RuntimeException("Redis transaction fail");
            }
        }

    这个方法其实是对redisTemplate对哈希表set操作的封装(上面其实是用了事务操作)

    2.getHashTable

    public Map<String, String> getHashTable(final String key) {
            try {
                HashOperations<String, String, String> operations = redisTemplate.opsForHash();
                Map<String, String> mapInRedis = operations.entries(generateKey(key));
                return mapInRedis;
            } catch (Exception e) {
                log.warn("redis get Exception.", e);
            }
            return MapUtils.EMPTY_MAP;
        }

     好吧,针对遇到的问题,我追踪了一下redisTemplate的源码,debug进上面代码中黄色的地方看一下

    我们可以看到,是调用的redisTemplate.execute方法。这个方法里面是对hGetAll的封装调用。

    那我们看一下redis相关文档里面对HGETALL的解释:http://redisdoc.com/hash/hgetall.html

    我们自己在终端实验一下:

    果然哈,输入一个不存在的key,返回的不是null,而是一个empty list or set

    那么程序里面返回的是{}就可以理解了。

     接下来查后面set进null值的问题。我们上述代码中调用的是putAll方法:

    看源码可以发现,这个方法写着,m 不可以为空。如果是null有什么后果呢

     这个方法里面已经假定m不为null了,直接判断是否为空的empty。那么其实如果m是null,是不会走进这个方法里面来的,至少m.isEmpty这里会报NPE。

    还没有周到具体的原因。那我猜应该是传入null的时候,报了空指针,某个地方拦截住然后把这个key锁住了

  • 相关阅读:
    css学习_css3伸缩布局 flex布局
    css学习_cs3s旋转的图片
    css学习_css3过渡
    css学习_css伪元素的本质
    css学习_css精灵技术、字体图标
    css学习_css用户界面样式
    Python 的 with 语句
    KNN--Python实现
    Python中NumPy(axis=0 与axis=1)
    Python中escape和unescape
  • 原文地址:https://www.cnblogs.com/sonofelice/p/9026477.html
Copyright © 2011-2022 走看看