You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 11:43:04