{"id":5690,"date":"2025-12-14T12:10:16","date_gmt":"2025-12-14T12:10:16","guid":{"rendered":"https:\/\/codethataint.com\/blog\/?p=5690"},"modified":"2025-12-14T12:32:05","modified_gmt":"2025-12-14T12:32:05","slug":"simple-program-using-shedlock","status":"publish","type":"post","link":"https:\/\/codethataint.com\/blog\/simple-program-using-shedlock\/","title":{"rendered":"Simple Program using shedlock"},"content":{"rendered":"<p><strong class=\"ctaHeader2\">Simple Shedlock Code<\/strong><\/p>\n<p><strong>pom.xml<\/strong><\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\t&lt;dependency&gt;\r\n\t\t\t&lt;groupId&gt;net.javacrumbs.shedlock&lt;\/groupId&gt;\r\n\t\t\t&lt;artifactId&gt;shedlock-spring&lt;\/artifactId&gt;\r\n\t\t\t&lt;version&gt;5.13.0&lt;\/version&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\t\t&lt;dependency&gt;\r\n\t\t\t&lt;groupId&gt;net.javacrumbs.shedlock&lt;\/groupId&gt;\r\n\t\t\t&lt;artifactId&gt;shedlock-provider-jdbc-template&lt;\/artifactId&gt;\r\n\t\t\t&lt;version&gt;5.13.0&lt;\/version&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\r\n<\/pre>\n<p><strong>ShedLockConfig.java<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport net.javacrumbs.shedlock.core.LockProvider;\r\nimport net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;\r\nimport org.springframework.context.annotation.Bean;\r\nimport org.springframework.context.annotation.Configuration;\r\nimport org.springframework.jdbc.core.JdbcTemplate;\r\n\r\nimport javax.sql.DataSource;\r\n\r\n@Configuration\r\npublic class ShedLockConfig {\r\n\r\n    @Bean\r\n    public LockProvider lockProvider(DataSource dataSource) {\r\n        return new JdbcTemplateLockProvider(\r\n                JdbcTemplateLockProvider.Configuration.builder()\r\n                        .withJdbcTemplate(new JdbcTemplate(dataSource))\r\n                        .withTableName(&quot;empmgmt.shedlock&quot;)\r\n                        .build()\r\n\r\n        );\r\n    }\r\n}\r\n<\/pre>\n<p><strong>ShedlockDemoApplication.java<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;\r\nimport org.springframework.boot.SpringApplication;\r\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\r\nimport org.springframework.scheduling.annotation.EnableScheduling;\r\n\r\n@SpringBootApplication\r\n@EnableScheduling\r\n@EnableSchedulerLock(defaultLockAtMostFor = &quot;PT4M&quot;)\r\npublic class ShedlockDemoApplication {\r\n    public static void main(String&#x5B;] args) {\r\n        SpringApplication.run(ShedlockDemoApplication.class, args);\r\n    }\r\n}\r\n<\/pre>\n<p><strong>PostFetchScheduler.java<\/strong><br \/>\nfetchPosts method is called every minute<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Component\r\nclass PostFetchScheduler {\r\n\r\n    final PostFetchService postFetchService;\r\n\r\n    PostFetchScheduler(PostFetchService postFetchService) {\r\n        this.postFetchService = postFetchService;\r\n    }\r\n\r\n    @Scheduled(cron = &quot;0 *\/1 * ? * *&quot;)\r\n    @SchedulerLock(name = &quot;fetchPosts&quot;, lockAtMostFor = &quot;PT2M&quot;, lockAtLeastFor = &quot;PT1M&quot;)\r\n    void fetchPosts() {\r\n        postFetchService.fetchPosts();\r\n    }\r\n}\r\n<\/pre>\n<p><strong>How to run the code<\/strong><\/p>\n<ol>\n<li>Shedlock table should be created manually in database\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n  CREATE TABLE shedlock (\r\n    name VARCHAR(64) NOT NULL,         -- lock name\r\n    lock_until TIMESTAMP NOT NULL,     -- time until lock is valid\r\n    locked_at TIMESTAMP NOT NULL,      -- time when lock was acquired\r\n    locked_by VARCHAR(255) NOT NULL,   -- identifier of the node that holds the lock\r\n    PRIMARY KEY (name)\r\n);\r\n  <\/pre>\n<\/li>\n<li>Start multiple instance by supplying server.port and instance name as parameter<\/li>\n<li>First instance would create table in DB for posts for code in repo <\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/codethataint.com\/blog\/wp-content\/uploads\/2025\/12\/SLMultiInst.png\" alt=\"\" \/><\/p>\n<p><strong>Output<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/codethataint.com\/blog\/wp-content\/uploads\/2025\/12\/SLMultiInst2.png\" alt=\"\" \/><\/p>\n<p><strong class=\"ctaHeader2\">FAQ<\/strong><br \/>\n<strong>Why we are defining lock timing at 2 places? <\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@EnableSchedulerLock(defaultLockAtMostFor = &quot;PT4M&quot;) \r\n <\/pre>\n<p>vs<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n  @SchedulerLock(name = &quot;fetchPosts&quot;, lockAtMostFor = &quot;PT2M&quot;, lockAtLeastFor = &quot;PT1M&quot;)\r\n <\/pre>\n<p><em>@EnableSchedulerLock<\/em> sets defaults for all tasks. A fallback setting for all tasks.<\/p>\n<p> <em>@SchedulerLock <\/em>gives per-task overrides with more precise control. Fine-grained control, overriding the default for specific jobs.<\/p>\n<p><a href=\"https:\/\/bitbucket.org\/Mugil\/codesnippets\/src\/ShedLockExample\/\">Repo Link<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Simple Shedlock Code pom.xml &lt;dependency&gt; &lt;groupId&gt;net.javacrumbs.shedlock&lt;\/groupId&gt; &lt;artifactId&gt;shedlock-spring&lt;\/artifactId&gt; &lt;version&gt;5.13.0&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;net.javacrumbs.shedlock&lt;\/groupId&gt; &lt;artifactId&gt;shedlock-provider-jdbc-template&lt;\/artifactId&gt; &lt;version&gt;5.13.0&lt;\/version&gt; &lt;\/dependency&gt; ShedLockConfig.java import net.javacrumbs.shedlock.core.LockProvider; import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @Configuration public class ShedLockConfig { @Bean public LockProvider lockProvider(DataSource dataSource) { return new JdbcTemplateLockProvider( JdbcTemplateLockProvider.Configuration.builder() .withJdbcTemplate(new JdbcTemplate(dataSource)) .withTableName(&quot;empmgmt.shedlock&quot;) .build() ); } } ShedlockDemoApplication.java import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock; import org.springframework.boot.SpringApplication; import&hellip; <a href=\"https:\/\/codethataint.com\/blog\/simple-program-using-shedlock\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372,371],"tags":[],"class_list":["post-5690","post","type-post","status-publish","format-standard","hentry","category-java-tools","category-spring-batch"],"_links":{"self":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts\/5690","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/comments?post=5690"}],"version-history":[{"count":5,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts\/5690\/revisions"}],"predecessor-version":[{"id":5699,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts\/5690\/revisions\/5699"}],"wp:attachment":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/media?parent=5690"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/categories?post=5690"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/tags?post=5690"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}