Spring Boot ShedLock solves a very common problem which occurs if you are running scheduled cron jobs in your application which is deployed in a distributed environment with shared database.

Spring by default, doesn’t provide a way to handle synchronization of cron jobs between multiple instance. It means spring will run your scheduler on multiple instances at the same time. ShedLock solves this problem. It will make sure your task with @Scheduled annotation is run only on one instance in your deployment setup. Spring Boot ShedLock uses external storage to keep a track of schedulers and locks. You need to have your application connected to a database for this to work. Check out: ShedLock on github.

Here are the steps to integrate shedlock in your spring boot applications. Make sure to go on to the github page of shedlock to read more about it.

Add ShedLock Dependency

Add maven dependency for Spring Boot ShedLock to you pom.xml.

<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-spring</artifactId>
    <version>4.24.0</version>
</dependency>

Create ShedLock Table

Depending on your database, create a table for ShedLock. Here is an example of MySQL table for shedlock:

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

Annotate your application with the ShedLock annotation

@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class YourApplicationWithSchedulers {
  public static void main(String[] args) {
    SpringApplication.run(YourApplicationWithSchedulers.class, args);
  }
}

Define LockProvider Bean

You can define this bean in your main application file, or just create a new configuration class.

@Configuration
public class ShedLockConfig {
  @Bean
  public LockProvider lockProvider(DataSource dataSource) {
    return new JdbcTemplateLockProvider(dataSource);
  }
}

Annotate Your Schedulers

The last thing you need to do is to annotate your schedulers.

public class YourTaskScheduler {
  @Scheduled(cron = "0 * * ? * *")
  @SchedulerLock(
      name = "UNIQUE_KEY_FOR_THIS_SCHEDULER",
      lockAtLeastForString = "PT1M", // lock for at least a minute, overriding the default setting here for each scheduler
      lockAtMostForString = "PT5M" // lock for at most 5 minutes
  )
  public void run() {
  
  // your task
} 

That’s it. The annotated schedulers will be locked for execution when one of your instance starts executing it and will not be executed concurrently on other instances.

You can check out ShedLock github for other databases and time durations. Let me know if this helped.

Share:

administrator

I am a full stack software engineer and a blogger. Primarily, I work on Python, Java and React.js. I am an autodidact with a strong passion for new technologies. I love to build new things from the ground up. I have about 7 years of dynamic experience gained by working in early stage startups to mid-sized organizations in an Agile environment.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.