Java Spring shedlock fails

5.9k views Asked by At

i have a spring-boot app, which on production environment runs in 2 instances, resulting in scheduled tasks running twice. to avoid that i'm trying use shedlock, as explained here and here, but it has no affect. i'm already using a MySql db, to which i added a shedlock table as explained on both of the examples above.

my project's structure is as follows (partially) -

enter image description here

in my application.properties file i have this settings -

db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/b4ad?autoReconnect=true&useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
db.username=*****
db.password=*****

to the AppConfig class i added this annotation -

@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")

and this bean -

@Bean
public LockProvider lockProvider(DataSource dataSource) {
    return new JdbcTemplateLockProvider(dataSource, "b4ad.shedlock");
}

and in the ScheduledManager class i have this scheduled task -

 @Scheduled(cron = "0 0/1 * * * ?")
@SchedulerLock(name = "deactivateExpiredOrganizations", lockAtLeastFor = "PT5M")
public void deactivateExpiredOrganizations() {
    // my code...
}

when i run my application locally on 2 instances (using 2 different ports in the application.properties file), looking at the log i can see that the task runs on both instances, and at the same time the shedlock table remains empty. according to the second item in the troubleshooting section, it seems that i miss-configured something, but i can't tell what.

any help will be appreciated.

2

There are 2 answers

0
eRez On BEST ANSWER

well, apparently in my big project there was another config class (besides the AppConfig) - one called SqlSpringConfig, inside the db module. once i put the LockProvider bean there, all works like a charm

0
jaejun On

You should check your taskConfiguration implementation.

I have same issue in my project. Problem is below code.

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
        threadPoolTaskScheduler.initialize();

        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

We add custom configuration by implementing ScheduledTaskRegistrar for using multi-threading to execute tasks. But if you override configureTasks, shedlock doesn't work. You should inject by using @Bean. So,

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    
        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("custom-scheduler-");
        threadPoolTaskScheduler.initialize();
    
        return threadPoolTaskScheduler;
    }

when i change override to inject by @Bean, it works well!