不会自动释放。redisson锁依赖redis key过期时间(默认30秒)兜底,但该机制仅防服务崩溃,不防优雅重启;重启时若业务未完成,shutdown hook常来不及执行unlock,且看门狗会持续续期,导致锁长期滞留。

Spring Boot进程重启时,Redisson锁会自动释放吗
不会自动释放。Redisson的锁默认靠Redis key过期时间(默认30秒)兜底,但这个机制只防“服务崩溃”,不防“优雅重启”。如果应用在lock.lock()后、业务未完成前触发重启(比如kill -15),JVM进程会执行shutdown hook,但unlock()是否来得及执行,取决于Spring容器关闭顺序和锁对象生命周期——而实际中经常来不及。
为什么不能只依赖Redis过期时间
过期时间只是保底策略,它解决的是“客户端宕机”场景;但Spring Boot重启是主动行为,线程还在运行、连接还活着,Redis不知道你要关了。此时:
• 锁key仍在Redis中存活,其他实例无法获取该锁
• 看门狗(watchdog)机制会持续续期,只要客户端连接没断,锁就一直不超时
• 重启后新进程用同一key重试加锁,tryLock()会失败,导致业务阻塞或降级
如何让重启时安全释放锁
核心思路:在Spring容器关闭前,主动遍历并释放当前线程持有的所有Redisson锁。关键点如下:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
RLock对象必须被显式持有并可追踪(不能只在方法栈内临时创建) - 使用
@PreDestroy或SmartLifecycle钩子,在close()阶段调用lock.unlock() - 避免在
finally块里释放——重启时finally不一定执行 - 若用
@DistributedLock这类AOP注解,需确保切面能注册销毁回调,否则锁对象不可达
示例片段:
@Component
public class LockHolder {
private final Map<string rlock> heldLocks = new ConcurrentHashMap();
public RLock acquire(String key) {
RLock lock = redissonClient.getLock(key);
if (lock.tryLock(3, 10, TimeUnit.SECONDS)) {
heldLocks.put(key, lock);
return lock;
}
return null;
}
@PreDestroy
public void releaseAll() {
heldLocks.values().forEach(lock -> {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
});
heldLocks.clear();
}
}
</string>
容易被忽略的细节
• RLock.isHeldByCurrentThread()必须检查,否则可能误删别人持有的锁
• 如果锁是可重入的(lock.lock()多次),unlock()也必须调用相同次数,否则锁不会真正释放
• 集群模式下,PreDestroy只作用于当前节点,不保证其他节点锁状态一致——RedLock需额外处理
• Spring Boot 3+ 的Graceful Shutdown配置(server.shutdown=graceful)能延长关闭窗口,但不改变锁释放逻辑本身










