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?
CodePudding user response:
You need to add @EnableSchedulerLock to your configuration class as per documents : "In order to enable schedule locking use @EnableSchedulerLock annotation"
CodePudding user response:
You need to add @EnableSchedulerLock annotation with manadatory parameter defaultLockAtMostFor on your main class from where spring boot application is starting. It will prevent multiple instances of same spring boot application to run scheduled task at a same time.