SpringBoot项目中如何检查指定Shedlock锁是否处于激活状态?
SpringBoot项目中如何检查指定Shedlock锁是否处于激活状态?
嘿,我刚好碰到过类似的需求,其实不用直接手动查询Shedlock的表,它本身就提供了原生的API或者可以通过Spring的组件来优雅实现这个功能,下面给你两种可行的方案:
方案一:使用Shedlock原生LockProvider接口
Shedlock的核心组件LockProvider提供了获取锁信息的方法,你可以直接注入对应的实现类(比如用JDBC存储的话就是JdbcTemplateLockProvider,Redis的话是RedisLockProvider),然后检查锁的激活状态:
import net.javacrumbs.shedlock.core.LockConfiguration; import net.javacrumbs.shedlock.core.LockProvider; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDateTime; import java.util.Optional; @RestController public class MyController { private final LockProvider lockProvider; // 构造函数注入(推荐) public MyController(LockProvider lockProvider) { this.lockProvider = lockProvider; } @GetMapping("/my-endpoint") public void myEndpoint() { // 获取指定名称的锁配置信息 Optional<LockConfiguration> lockConfig = lockProvider.getCurrentLock("batch_lock_1"); if (lockConfig.isPresent()) { LockConfiguration config = lockConfig.get(); LocalDateTime now = LocalDateTime.now(); // 判断当前时间是否处于锁的有效区间内 if (now.isAfter(config.getLockedAt()) && now.isBefore(config.getLockUntil())) { throw new BadRequestException("Batch 1 is currently running"); } } // 后续业务逻辑 } }
这个方案的优势是完全贴合Shedlock的设计,不需要自己定义实体类,而且适配不同的锁存储方式(JDBC、Redis等)。
方案二:通过Spring Data JPA查询锁表(适合JDBC存储场景)
如果你更习惯用Spring Data的方式操作数据库,也可以定义对应的实体类和Repository来查询锁状态,这种方式更直观:
1. 定义Shedlock实体类
import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; import java.time.LocalDateTime; @Entity @Table(name = "shedlock") // 对应你创建的Shedlock表名 public class ShedlockEntity { @Id @Column(name = "name", nullable = false) private String name; @Column(name = "lock_until", nullable = false) private LocalDateTime lockUntil; @Column(name = "locked_at", nullable = false) private LocalDateTime lockedAt; @Column(name = "locked_by", nullable = false) private String lockedBy; // Getter和Setter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public LocalDateTime getLockUntil() { return lockUntil; } public void setLockUntil(LocalDateTime lockUntil) { this.lockUntil = lockUntil; } public LocalDateTime getLockedAt() { return lockedAt; } public void setLockedAt(LocalDateTime lockedAt) { this.lockedAt = lockedAt; } public String getLockedBy() { return lockedBy; } public void setLockedBy(String lockedBy) { this.lockedBy = lockedBy; } }
2. 创建Repository接口
import org.springframework.data.jpa.repository.JpaRepository; public interface ShedlockRepository extends JpaRepository<ShedlockEntity, String> { }
3. 在接口中使用
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDateTime; import java.util.Optional; @RestController public class MyController { private final ShedlockRepository shedlockRepository; public MyController(ShedlockRepository shedlockRepository) { this.shedlockRepository = shedlockRepository; } @GetMapping("/my-endpoint") public void myEndpoint() { Optional<ShedlockEntity> lockEntity = shedlockRepository.findById("batch_lock_1"); if (lockEntity.isPresent()) { ShedlockEntity entity = lockEntity.get(); LocalDateTime now = LocalDateTime.now(); if (now.isAfter(entity.getLockedAt()) && now.isBefore(entity.getLockUntil())) { throw new BadRequestException("Batch 1 is currently running"); } } // 后续业务逻辑 } }
需要注意的是,这个方案只适用于JDBC存储的Shedlock,如果你用的是Redis等其他存储方式,就需要对应调整查询逻辑啦。
备注:内容来源于stack exchange,提问作者Natty
相关产品推荐
相关产品推荐

