Three replicas of one application against one PostgreSQL database, proving duplicate @Scheduled execution and then removing it with ShedLock: 24 executions where 8 were due, then 7 for 7 ticks. Also measured: @SchedulerLock without @EnableSchedulerLock does nothing and warns about nothing; spring.task.scheduling.pool.size=1 does not starve a fixedRate job but delays it and fires 35 of 40 executions in a burst; and a node whose clock is 40 seconds fast takes a live lock unless the provider uses usingDbTime().
18 lines
687 B
Plaintext
18 lines
687 B
Plaintext
== One lock, two holders: what usingDbTime() prevents ==
|
|
|
|
lockAtMostFor = 30s, both callers ask for the same lock name.
|
|
|
|
JdbcTemplateLockProvider WITHOUT usingDbTime()
|
|
node with a correct clock : acquired
|
|
node with a clock 40s fast : ACQUIRED -- two holders at the same time
|
|
|
|
JdbcTemplateLockProvider WITH usingDbTime()
|
|
node with a correct clock : acquired
|
|
node with a clock 40s fast : refused
|
|
|
|
Without usingDbTime() the expiry comparison happens against the calling
|
|
JVM's clock, so a node that is ahead by more than lockAtMostFor considers
|
|
every live lock expired. With it, both the write and the comparison happen
|
|
in the database, and there is only one clock in the system.
|
|
|