Redis设置过期时间失效(导致拿不到锁)

这几天项目做了个定时任务,刚开始好着,后来一直没数据,看日志显示没拿到锁(拿key返回false)

总结一下,各位也避免这样😂 (想直接知道结果的请翻至最底↓💣):


刚开始🙏

设置RedisService 获取锁的方法

    /**
     * 获取锁,设置过期时间(s)
     * @param key key
     * @param value 值
     * @param outTime 超时时间s
     * @return java.lang.Boolean
     */
public Boolean lock(String key, String value, long outTime) {
        return redisTemplate.opsForValue().setIfAbsent(key, value, outTime, TimeUnit.SECONDS);
    }

后来第二天再次去执行任务:

查看日志直接报错,显示拿不到锁,导致任务没有执行


发现问题所在😏

虽然第一次设置了这个lockKey的过期时间,但是后来在后面对这个key再次进行了设置值

这就是问题的所在😅!!!

举个栗子🌰:

Boolean test = redisService.lock("test", "1", 10);
log.info(String.valueOf(test));
Boolean test1 = redisService.lock("test", "1", 10);
log.info(String.valueOf(test1));
redisService.set("test", "2");

结果:👇

这样看,确实没错,当执行到第五✋行,也就是设置值之后,再次去redis查看他的过期时间

他的TTL成了 -1 !!!

总结📏

虽然之前对某个key设置了过期时间,但!如果再次进行赋值(用DEL, SET, GETSET会将key对应存储的值替换成新的),没有在后面expire,就会把过期时间覆盖掉,变成无限存活,也就是-1。

'-1' 如果不明白的童鞋看下面👇👇


Tips📌

TTL 命令以秒为单位返回 key 的剩余过期时间。

  • 当 key 不存在时,返回 -2 。

  • 当 key 存在但没有设置剩余生存时间时,返回 -1 。

  • 否则,以秒为单位,返回 key 的剩余生存时间。

注意:在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1 。


栗子🌰:

# 不存在的 key

redis> TTL key
(integer) -2

redis> SET mykey "Hello"
"OK"

# key 存在,但没有设置剩余生存时间

redis> TTL mykey
(integer) -1

# 有剩余生存时间的 key

redis> EXPIRE key 10086
(integer) 1

另一种解决方法😁:

说是解决方法,也可以说是一种习惯--->

在有必要的前提下,可以给代码加入try-catch-finally在finally中进行释放锁

try {
        boolean lock = redisService.lock(lockKey, "1",10 * 60);
        if (!lock) {
            log.info("未获取到锁,不需要执行");
        }
    }catch (Exception e){
        log.error("异常: ", e);
    }finally {
        redisService.unLock(lockKey);
 }

这样之后不管这个key有没有进行过期操作 -> 都可以在程序执行之后进行“处理”

    /**
     * 解锁
     */
    public Boolean unLock(String key) {
        return this.delete(key);
    }

当然,在写代码当中也需要去注意这种前后影响问题!!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值