Redisson加锁失败典型异常包括RedisTimeoutException、NoConnectionAvailableException等,需分层捕获并针对性处理;tryLock()返回false属正常流程,须显式判断而非依赖异常捕获。

Redisson 的 RedisException 是运行时异常(unchecked),加锁失败时通常不会直接抛出它,而是抛出更具体的子类(如 RedisTimeoutException、NoConnectionAvailableException 等),或在特定场景下由用户代码触发。捕获的关键在于:**区分加锁超时、连接异常、业务逻辑中断等不同失败原因,并针对性处理**。
明确哪些异常属于加锁失败的典型情况
Redisson 加锁(如 RLock.lock() 或 tryLock())失败时,常见异常包括:
-
RedisTimeoutException:等待锁超时(例如lock(10, TimeUnit.SECONDS)超过 10 秒未获取到锁) -
NoConnectionAvailableException:Redis 连接池耗尽,无法获取 Redis 连接 -
RedisConnectionClosedException:连接已关闭(如网络闪断、Redis 重启) -
IllegalStateException:调用unlock()但锁已被释放或不属于当前线程(属于使用错误,非加锁失败,但常被误判) -
RedisException及其子类:父类,可兜底捕获所有 Redisson 底层通信异常
推荐的捕获方式:按需分层处理
不建议只 catch RedisException 一个泛型异常,而应优先捕获具体子类,再兜底处理:
RLock lock = redissonClient.getLock("my:lock:key");
try {
// 尝试加锁,最多等 3 秒,持有锁 30 秒
if (!lock.tryLock(3, 30, TimeUnit.SECONDS)) {
// 未获取到锁(非异常,是正常业务流)
throw new BusinessException("获取分布式锁失败,资源正被占用");
}
// 执行业务逻辑
doSomething();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢复中断状态
throw new BusinessException("加锁过程被中断", e);
} catch (RedisTimeoutException e) {
// 明确知道是等待锁超时
log.warn("获取锁超时,key={}", "my:lock:key", e);
throw new BusinessException("系统繁忙,请稍后重试", e);
} catch (NoConnectionAvailableException | RedisConnectionClosedException e) {
// Redis 连接问题,可能是临时故障
log.error("Redis 连接异常,无法加锁", e);
throw new ServiceException("服务暂不可用", e);
} catch (RedisException e) {
// 兜底:捕获其他 Redisson 相关异常(如序列化失败、命令执行异常等)
log.error("Redisson 操作异常", e);
throw new ServiceException("分布式锁服务异常", e);
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
注意 tryLock() 返回 false 不是异常,别漏掉这个分支
tryLock(long waitTime, long leaseTime, TimeUnit unit) 在超时时间内没拿到锁时,**返回 false,不抛异常**。这是最常见“加锁失败”场景,必须显式判断:
立即学习“Java免费学习笔记(深入)”;
- 不能只依赖
catch,否则会忽略该情况 - 返回
false通常意味着竞争激烈或锁长期被占用,适合做降级、重试或提示 - 若业务允许,可配合指数退避重试(注意避免雪崩)
增强健壮性的实用建议
-
设置合理超时参数:
waitTime太长会阻塞线程,太短易失败;leaseTime要大于最长业务执行时间(建议加 20% 缓冲) - 启用 Redisson 的看门狗机制:默认开启,自动续期锁(避免业务卡住导致锁过期误删),无需手动干预
- 日志记录关键信息:锁 key、等待时长、当前线程、异常堆栈,便于排查是竞争问题还是基础设施故障
- 避免在锁内做远程调用或 IO 阻塞操作:防止 leaseTime 不足导致锁提前释放


















