概述
redis系列文章目录
- 使用spring-data-redis实现incr自增
- Redis 利用Hash存储节约内存
- Redis学习笔记(九)redis实现时时直播列表缓存,支持分页[热点数据存储]
- Redis学习笔记(八)redis之lua脚本学习
- Redis学习笔记(七)jedis超时重试机制注意事项
- Redis学习笔记(六)redis实现分布式锁
- Redis学习笔记(五)jedis(JedisCluster)操作Redis集群 redis-cluster
- redis学习笔记(四)缓存与数据库一致性问题
- redis学习笔记(三)数据淘汰策略
- redis学习笔记(二)JedisCluster + redis 3.2.5集群
- redis学习笔记(一)redis3.2.5集群安装与测试
应该有不少人在使用spring-data-redis时遇到各种各样的问题。反正我是遇到了。
由于是隔了一段时间才写的本篇博客,也懒得去重现哪些错误场景了,下面凭着记忆写了几个我遇到的问题:
redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of range
使用的RedisTemplate
,做读写操作时候,都是要经过序列化和反序列化。这时你使用redisTemplate.opsForValue().increment()
就可能报错redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of range
了。
valueOper.get(key) 获取不到自增的值。
于是我去看了一下redis的官方文档,找到一个解决方法
使用spring-data-redis实现incr自增
/**
*
* @param key
* @param liveTime
* @return
*/
public Long incr(String key, long liveTime) {
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long increment = entityIdCounter.getAndIncrement();
if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间
entityIdCounter.expire(liveTime, TimeUnit.SECONDS);
}
return increment;
}
这样,上面的increment
就是自增后的新知值,然后中间通过entityIdCounter.expire(liveTime, TimeUnit.SECONDS);
设置过期时间。当然这里比较讨厌,spring没有在创建RedisAtomicLong
对象的时候一起设置过期时间。可以看看其源码,new RedisAtomicLong
最终调用的是这个方法:
private RedisAtomicLong(String redisCounter, RedisConnectionFactory factory, Long initialValue) {
Assert.hasText(redisCounter, "a valid counter name is required");
Assert.notNull(factory, "a valid factory is required");
RedisTemplate<String, Long> redisTemplate = new RedisTemplate<String, Long>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
redisTemplate.setExposeConnection(true);
redisTemplate.setConnectionFactory(factory);
redisTemplate.afterPropertiesSet();
this.key = redisCounter;
this.generalOps = redisTemplate;
this.operations = generalOps.opsForValue();
if (initialValue == null) {
if (this.operations.get(redisCounter) == null) {
set(0);
}
} else {
set(initialValue);
}
}
可以看到,初始值是0。
然后根进set
方法
public void set(long newValue) {
operations.set(key, newValue);
}
可以看到,他是采用的operations.set(key, newValue);
但是明明还有一个重载的方法void set(K key, V value, long timeout, TimeUnit unit);
可以设置过期时间,为啥spring不提供呢。
为了解决这个问题,我们可以自己模拟RedisAtomicLong
方法,去实现一个带有过期时间的自增方法。比较简单,读者自行撸代码吧,这里就不写出了。
最后
以上就是魁梧小天鹅为你收集整理的使用spring-data-redis实现incr自增redis系列文章目录使用spring-data-redis实现incr自增的全部内容,希望文章能够帮你解决使用spring-data-redis实现incr自增redis系列文章目录使用spring-data-redis实现incr自增所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复