使用Shedlock做分布式调度时任务异常如何手动解锁
Shedlock 异常时手动释放锁实现方案
存在可直接落地的手动解锁实现方式,具体操作如下:
方式1:代码内异常触发自动解锁(推荐)
Shedlock 原生提供了LockRepository组件用于直接操作锁状态,你可以通过以下步骤实现异常时自动解锁:
- 注入
LockRepository实例到你的定时任务类中 - 在异常捕获块中调用解锁方法,传入的锁名称必须和
@SchedulerLock注解的name属性完全一致
完整代码示例:
import net.javacrumbs.shedlock.core.LockRepository; import org.springframework.beans.factory.annotation.Autowired; import lombok.extern.slf4j.Slf4j; @Slf4j // 你的定时任务类 public class YourJobClass { @Autowired private LockRepository lockRepository; @Scheduled(cron = "0 49 14 * * *") @SchedulerLock(name = "unlock-when-error", lockAtMostFor = "14m", lockAtLeastFor = "4m") public void deviceMasterJob() { try{ // 执行业务逻辑 }catch(Exception e){ // 手动释放指定名称的锁 lockRepository.unlock("unlock-when-error"); // 其他异常处理逻辑,如日志打印、告警推送 log.error("deviceMasterJob执行异常,已手动释放分布式锁", e); } // 无异常时不需要手动操作,Shedlock会自动按配置规则释放锁 } }
方式2:线上紧急手动解锁(无需修改代码)
如果是线上任务异常卡死需要临时释放锁,可直接操作Shedlock的底层存储:
- 若使用JDBC作为存储:直接修改默认
shedlock表中name为unlock-when-error的记录,将lock_until字段值更新为当前时间之前的任意值,锁就会立即释放 - 若使用Redis、MongoDB等其他存储:同理找到对应锁的key/文档,修改过期时间为已过期即可
注意事项
- 手动解锁会跳过
lockAtLeastFor配置的最短锁持有时间限制,立即释放锁 - 锁名称必须和
@SchedulerLock的name属性完全匹配,否则会释放失败 - 正常执行的任务不需要手动操作,Shedlock会在任务执行完成且满足
lockAtLeastFor时长要求后自动释放锁
内容的提问来源于stack exchange,提问作者testaaaa
相关产品推荐
相关产品推荐

