Search code examples
springconcurrencyscheduled-tasksschedulershedlock

Shedlock only works on one instance, but not multiple


I would like to setup Shedlock to guard a sensitive process so that only ONE instance of the process ever runs even when multiple application processes are started.

In my pom.xml

        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-spring</artifactId>
        </dependency>
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-jdbc-template</artifactId>
        </dependency>

My DB:

CREATE TABLE shedlock(
    name VARCHAR(64) NOT NULL,
    lock_until TIMESTAMP NOT NULL,
    locked_at TIMESTAMP NOT NULL,
    locked_by VARCHAR(255) NOT NULL,
    PRIMARY KEY (name));

My configuration:

@Configuration
@EnableScheduling
public class ShedlockConfiguration {
    @Bean
    public LockProvider lockProvider(DataSource dataSource) {
        return new JdbcTemplateLockProvider(
                JdbcTemplateLockProvider.Configuration.builder()
                        .withJdbcTemplate(new JdbcTemplate(dataSource))
                        .usingDbTime() 
                        .build()
        );
    }

}

My schedule:


@Component
public class SchedulerA {
    @Scheduled(initialDelayString = "${examples.scheduler.initial-delay:PT1S}",
            fixedDelayString = "${examples.scheduler.fixed-delay:PT10S}")
    @SchedulerLock(name = "example_scheduler",
            lockAtLeastFor = "${examples.scheduler.lock-at-least:PT5S}",
            lockAtMostFor = "${examples.scheduler.lock-at-most:PT30S}")
    public void schedule() {
// Implementation not important
    }

}

Symptom: If I start only one instance with multiple SchedulerA classes like SchedulerB, SchedulerC, etc which are all copies of the same code I can see the Shedlock does its thing and only allow one LOCAL instance to execute at a time. But, when I start up multiple Spring Boot applications, they all their schedules concurrently even when they use the same DB, same table, same scheduler name. I also notice no entries in the DB table, but the debug logs also reveals no errors.

Question: Is this the expected behaviour of Shedlock? Should I research another solution or did I misconfigured something?


Solution

  • You need to add @EnableSchedulerLock to your configuration class as per documents : "In order to enable schedule locking use @EnableSchedulerLock annotation"