Redisson解锁失败,WatchDog会不会一直续期下去?

目录

[一、WatchDog 底层续期规则(Redisson 自动续期锁,只针对lock()无过期时间的锁)](#一、WatchDog 底层续期规则(Redisson 自动续期锁,只针对lock()无过期时间的锁))

二、分场景详解解锁失败

[场景 1:unlock () 抛出异常解锁失败,但业务代码正常执行完毕,线程退出](#场景 1:unlock () 抛出异常解锁失败,但业务代码正常执行完毕,线程退出)

[场景 2:unlock 没执行、业务线程卡死(死循环 / 阻塞 / 休眠永不结束)→ 解锁彻底失败](#场景 2:unlock 没执行、业务线程卡死(死循环 / 阻塞 / 休眠永不结束)→ 解锁彻底失败)

[场景 3:Redis 手动 del 删除锁,代码 unlock 失败](#场景 3:Redis 手动 del 删除锁,代码 unlock 失败)

三、如何避免解锁失败导致无限续期死锁?


解锁正常调用 unlock() 成功 → WatchDog 立刻停止续期;解锁失败(代码抛异常、手动删 key、解锁逻辑报错)分两种场景:

  1. 业务线程正常结束(方法走完 /return):WatchDog 自动停止续期,不会永久续命
  2. 业务线程卡死死循环 / 阻塞永不退出 + unlock 没执行成功:WatchDog 会无限续期,锁永久占用

一、WatchDog 底层续期规则(Redisson 自动续期锁,只针对lock()无过期时间的锁)

只有不带 leaseTime 参数的 RLock.lock() 才开启看门狗续期;lock(10, TimeUnit.SECONDS) 指定过期时间,没有 WatchDog

  • 默认续期间隔:锁过期时间/2 = 15s(默认锁超时 30s),每 15s 异步刷新锁过期为 30s
  • 看门狗依附「持有锁的业务线程生命周期」:业务线程存活 → 定时任务一直跑;线程终止 → 定时任务被取消,续期停止。

二、分场景详解解锁失败

场景 1:unlock () 抛出异常解锁失败,但业务代码正常执行完毕,线程退出

复制代码
RLock lock = redissonClient.getLock("key");
lock.lock();
try {
    // 业务逻辑正常跑完
}finally {
    lock.unlock(); // unlock内部异常,解锁失败
}
  • finally 执行完,当前持有锁的业务线程结束 → WatchDog 的定时续期任务被 cancel ()
  • 锁不再续期,等待30s 自动过期释放,不会死锁。

unlock 源码:解锁无论成功失败,只要线程结束,看门狗任务被注销。

场景 2:unlock 没执行、业务线程卡死(死循环 / 阻塞 / 休眠永不结束)→ 解锁彻底失败

复制代码
lock.lock();
try{
    while(true){ // 线程无限死循环,永不跳出try
        // 死循环卡死
    }
}finally {
    // 代码永远进不到finally,unlock从未执行
}
  1. 线程一直存活,WatchDog 定时任务持续执行
  2. 每 15s 续期锁 30s → 锁无限续命,死锁常驻 Redis

这是线上最容易出现死锁的场景。

场景 3:Redis 手动 del 删除锁,代码 unlock 失败

Redis 客户端手动DEL key把锁删掉:

  • 下次看门狗续期时,setnx 刷新过期失败,直接取消续期任务,不再续约。

三、如何避免解锁失败导致无限续期死锁?

  1. unlock 必须放到 finally 中,保证必定执行解锁逻辑

  2. 业务增加超时保护:子任务设置超时熔断,避免线程永久卡死

  3. 担心 WatchDog 死续期:改用lock(30, TimeUnit.SECONDS)手动指定过期,关闭看门狗,超时自动释放

  4. 捕获 unlock 异常,兜底补偿解锁:

    finally {
    try {
    if(lock.isHeldByCurrentThread()){
    lock.unlock();
    }
    }catch (Exception e){
    // 解锁异常兜底,可发告警
    }
    }

isHeldByCurrentThread():校验当前线程是否持有锁,防止释放别人的锁抛异常

相关推荐
wuqingshun3141598 小时前
MYSQL的乐观锁和悲观锁是什么?
java
唐青枫8 小时前
Java SLF4J 实战指南:从日志门面到 Logback、MDC 和链路追踪
java
jvmind_dev9 小时前
Java GC 实战指南(番外篇):被忽视的隐形杀手 —— Class Unloading 如何拖垮 GC
java·后端
An_s9 小时前
机器学习python之识别图中物品信息
java·linux·开发语言
AIGS0019 小时前
跨越语义鸿沟:企业本体语义平台的构建与落地
java·人工智能·python·机器学习·人工智能ai大模型应用
snow@li10 小时前
Redis:数据库语法速查表 / 全景梳理
数据库·redis·缓存
蓝田~10 小时前
大模型本地部署与远程调用 — 从 API 到 Agent
java·人工智能·claude·claude code
码农进化录10 小时前
Java 程序员的 AI 进化论 | Spring Boot 接入 OpenAI 的六个坑,全帮你踩了
java·spring boot·openai
疯狂成瘾者11 小时前
Java 常见集合方法
java·windows·python
从此以后自律11 小时前
ConcurrentHashMap 超详细详解
java