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锁住了
redisTemplate写哈希表遇到的坑的更多相关文章
- [Codevs 1230]元素查找(手写哈希表)
题目连接:http://codevs.cn/problem/1230/ 说白了就是要我们自己手写一个哈希表的数据结构来实现加入和查找功能.map也能直接过(我第一次写就是用map骗AC的) 提一下个人 ...
- PTA 7-42 整型关键字的散列映射(手写哈希表的线性探测法)
本题考点: 整型哈希表的线性探测法 给定一系列整型关键字和素数P,用除留余数法定义的散列函数将关键字映射到长度为P的散列表中.用线性探测法解决冲突. 输入格式: 输入第一行首先给出两个正整数N(≤10 ...
- 哈希表的C实现(三)---传说中的暴雪版
关于哈希表C实现,写了两篇学习笔记,不过似乎网上流传最具传奇色彩的莫过于暴雪公司的魔兽文件打包管理器里的hashTable的实现了:在冲突方面的处理方面,采用线性探测再散列.在添加和查找过程中进行了三 ...
- LeetCode通关:哈希表六连,这个还真有点简单
精品刷题路线参考: https://github.com/youngyangyang04/leetcode-master https://github.com/chefyuan/algorithm-b ...
- 【哈希表】CodeVs1230元素查找
一.写在前面 哈希表(Hash Table),又称散列表,是一种可以快速处理插入和查询操作的数据结构.哈希表体现着函数映射的思想,它将数据与其存储位置通过某种函数联系起来,其在查询时的高效性也体现在这 ...
- 漫谈Linux内核哈希表(1)
关于哈希表,在内核里设计两个很重要的数据结构: 哈希链表节点: 点击(此处)折叠或打开 .x [include/linux/types.h]*/ struct hlist_node { stru ...
- noip模拟赛 好元素 哈希表的第一题
这是一道关于 题2好元素 2s [问题描述] 小A一直认为,如果在一个由N个整数组成的数列{An}中,存在以下情况: Am+An+Ap = Ai (1 <= m, n, p < i < ...
- c# 哈希表跟函数
一.哈希表集合 先进后出,一个一个赋值,但只能一起取值. 1.哈希表的建立.赋值以及读取. 2.利用枚举类型打印出集合中的Key值和Value值. 二.函数 函数:能够独立完成某项功能的模块. 函数四 ...
- Redis哈希表的实现要点
Redis哈希表的实现要点 哈希算法的选择 针对不同的key使用不同的hash算法,如对整型.字符串以及大小写敏感的字符串分别使用不同的hash算法: 整型的Hash算法使用的是Thomas Wang ...
随机推荐
- zepto中的tap穿透
有一个项目,浮层上是有点击的按钮,但是用tap就会穿透,触发浮层下的页面的点击事件.后来问同事和经过自己尝试,发现用click就可以解决这个问题.
- systemd启动多实例
最近用了centos7,启动管理器用的是systemd,感觉很好玩. 1.开机自动启动 新建一个service文件放到/usr/lib/systemd/system/ 比如: [Unit] Descr ...
- Android基础总结(二)布局,存储
常见布局 相对布局 RelativeLayout 组件默认左对齐.顶部对齐 设置组件在指定组件的右边 android:layout_toRightOf="@id/tv1" 设置在指 ...
- 如何解决PHP里大量数据循环时内存耗尽的问题
最近在开发一个PHP程序时遇到了下面的错误: PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted 错误信息显示允许的 ...
- python的post请求抓取数据
python通过get方式,post方式发送http请求和接收http响应-urllib urllib2 python通过get方式,post方式发送http请求和接收http响应-- import ...
- 阿里云ecs开启x11图形化桌面
阿里云帮助文档:https://www.alibabacloud.com/help/zh/faq-detail/41227.htm 安装云服务器 ECS CentOS 7 图形化桌面 以安装 MATE ...
- 错题0913-java
子类A继承父类B, A a = new A(); 则父类B构造函数.父类B静态代码块.父类B非静态代码块.子类A构造函数.子类A静态代码块.子类A非静态代码块 执行的先后顺序是? A:父类B静态代码块 ...
- 第二百四十五节,Bootstrap标签页和工具提示插件
Bootstrap标签页和工具提示插件 学习要点: 1.标签页 2.工具提示 本节课我们主要学习一下 Bootstrap 中的标签页和工具提示插件. 一.标签页选项卡 标签页也就是通常所说的选项卡功能 ...
- c#后台List转为js对象(在前台操作)
<!-- 用html标签防止html转义 (html.raw方法转双引号中的双引号时不会转义) --><input id="json" type="hi ...
- PHP cURL库函数抓取页面内容
目录 1 为什么要用cURL? 2 启用cURL 3 基本结构 4 检查错误 5 获取信息 6 基于浏览器的重定向 7 用POST方法发送数据 8 文件上传 9 cURL批处理(multi cURL) ...