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

Spring Boot中如何为定时任务配置多LockProvider实现分表ShedLock?

问题描述

我在Spring Boot中尝试创建两个ShedLock配置,以便通过不同的数据库表为定时任务加锁,已定义如下两个LockProvider Bean:

// 主锁提供者
@Bean("mainLockProvider")
public LockProvider mainLockProvider(DataSource dataSource) {
    return new JdbcTemplateLockProvider(
            JdbcTemplateLockProvider.Configuration.builder()
                    .withJdbcTemplate(new JdbcTemplate(dataSource))
                    .usingDbTime()
                    .withTableName("main_shedlock_table")
                    .build());
}

// 副锁提供者
@Bean("secondaryLockProvider")
public LockProvider secondaryLockProvider(DataSource dataSource) {
    return new JdbcTemplateLockProvider(
            JdbcTemplateLockProvider.Configuration.builder()
                    .withJdbcTemplate(new JdbcTemplate(dataSource))
                    .usingDbTime()
                    .withTableName("secondary_shedlock_table")
                    .build());
}

但定义定时任务时发现无法指定使用哪个LockProvider,因为@SchedulerLock注解不支持传入LockProvider参数:

@Scheduled(cron = "*/5 * * * *")
@SchedulerLock(name = "some_scheduled_task", lockAtLeastFor = "PT15S", lockAtMostFor = "PT1M")
public void scheduledTaskUsingMainLockProvider() {
  // 本应在main_shedlock_table中创建锁记录
}

@Scheduled(cron = "*/5 * * * *")
@SchedulerLock(name = "some_other_scheduled_task", lockAtLeastFor = "PT15S", lockAtMostFor = "PT1M")
public void scheduledTaskUsingSecondaryLockProvider() {
  // 本应在secondary_shedlock_table中创建锁记录
}

请问是否可以实现让不同定时任务使用对应LockProvider的需求?


解决方案

可以实现,核心思路是创建多组独立的ShedLock配置,每组配置对应自己的LockProvider,并通过方法过滤规则让不同的定时任务匹配到对应的锁配置。

1. 自定义标记注解(可选但直观)

创建两个自定义注解,用来标记不同组的定时任务,方便后续切面识别:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseMainLock {
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseSecondaryLock {
}

2. 配置多组ShedLock切面

针对每个LockProvider,单独构建ScheduledLockConfiguration,并通过withInterceptorMethodFilter指定该切面只处理对应标记的任务:

@Configuration
public class MultipleShedLockConfig {

    // 主锁对应的ShedLock配置
    @Bean
    public ScheduledLockConfiguration mainShedLockConfiguration(
            @Qualifier("mainLockProvider") LockProvider mainLockProvider,
            TaskScheduler taskScheduler) {
        return ScheduledLockConfigurationBuilder
                .withLockProvider(mainLockProvider)
                .withTaskScheduler(taskScheduler)
                // 只拦截带有@UseMainLock和@Scheduled的方法
                .withInterceptorMethodFilter(method -> 
                        method.isAnnotationPresent(UseMainLock.class) && method.isAnnotationPresent(Scheduled.class))
                .build();
    }

    // 副锁对应的ShedLock配置
    @Bean
    public ScheduledLockConfiguration secondaryShedLockConfiguration(
            @Qualifier("secondaryLockProvider") LockProvider secondaryLockProvider,
            TaskScheduler taskScheduler) {
        return ScheduledLockConfigurationBuilder
                .withLockProvider(secondaryLockProvider)
                .withTaskScheduler(taskScheduler)
                // 只拦截带有@UseSecondaryLock和@Scheduled的方法
                .withInterceptorMethodFilter(method -> 
                        method.isAnnotationPresent(UseSecondaryLock.class) && method.isAnnotationPresent(Scheduled.class))
                .build();
    }
}

3. 给定时任务添加标记注解

修改定时任务方法,加上对应的自定义注解,让任务匹配到指定的锁配置:

@Scheduled(cron = "*/5 * * * *")
@UseMainLock
@SchedulerLock(name = "some_scheduled_task", lockAtLeastFor = "PT15S", lockAtMostFor = "PT1M")
public void scheduledTaskUsingMainLockProvider() {
  // 现在会使用main_shedlock_table中的锁记录
}

@Scheduled(cron = "*/5 * * * *")
@UseSecondaryLock
@SchedulerLock(name = "some_other_scheduled_task", lockAtLeastFor = "PT15S", lockAtMostFor = "PT1M")
public void scheduledTaskUsingSecondaryLockProvider() {
  // 现在会使用secondary_shedlock_table中的锁记录
}

补充说明

  • 如果你不想用自定义注解,也可以通过方法的包路径、方法名前缀等规则来过滤任务,比如method.getDeclaringClass().getPackageName().startsWith("com.xxx.main")。
  • 确保两个ScheduledLockConfiguration Bean都被Spring正确扫描到,Spring会自动处理多个切面的逻辑,不会出现冲突。

内容的提问来源于stack exchange,提问作者Natty

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 23:19:55