I have 4 servers and JVM is installed on them. I wrote a java service that Quartz calls this services every 10 minutes. But in 4 servers, every 10 minutes 4 calls are done. This sitiuation creates race condition. I want only one service on 4 JVM.
How can I do that with Spring Framework?
This is actually pretty easy to set up with Quartz. Spring itself cannot help you much here since it is unaware of the other JVMs that are running. Quartz on the other hand has the concept of a clustered scheduler.
Basically you need to set up a single database that all the 4 JVMs can share. This will be used as a scheduler for all 4 instances. When a job is scheduled, it is run by only one of the instances using the clustered scheduler.
Taken from the Quartz website wiki for clustering ( http://www.opensymphony.com/quartz/wikidocs/ConfigJDBCJobStoreClustering.html), this is an example configuration on how to set up the clustered scheduler. You can also set these properties directly from spring if you are configuring your scheduler that way.
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@polarbear:1521:dev
org.quartz.dataSource.myDS.user = quartz
org.quartz.dataSource.myDS.password = quartz
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
Your question isn't very clear, so let me see if I'm understanding you: you have 4 servers, each running Quartz inside a VM, and each server has the same quartz job scheduled to run every 10 minutes, using a cron expression. Every 10 minutes, all 4 servers kick off the same job, creating your race condition as they all try to do the same thing at the same time.
This isn't really a job for Spring. However, Quartz does have clustering ability, where you configure a job to run only a single server in the cluster. It uses a shared database to coordinate which servers run which job, and makes sure they don't all do it together.
The docs have some info on this here, but in the usual opensymphony.com style they're pretty sparse and unhelpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With