I have a Spring schedulled tasks which calls the same private method. Do I need to sync this method? Will I have the problem if shedulled tasks runned in the same time? Or will be better to extract it to the prototype component or separate schedulled classes or something else?
public class SomeScheduled { private final RequestDispatcher requestDispatcher; private final ErrorRegisterRepository errorRegisterRepository; @Scheduled(cron = "0 0/4 * * * ?") public void runRetry4minute() { runRetry(Duration.of(4, ChronoUnit.MINUTES), 1); } @Scheduled(cron = "0 0/11 * * * ?") public void runRetry11minute() { runRetry(Duration.of(11, ChronoUnit.MINUTES), 2); } @Scheduled(cron = "0 0/29 * * * ?") public void runRetry29minute() { runRetry(Duration.of(29, ChronoUnit.MINUTES), 3); } private void runRetry(TemporalAmount time, int someField) { LocalDateTime dateTime = LocalDateTime.now().minus(time); Page<ErrorRegister> page; int pageNum = 0; do { page = errorRegisterRepository.findBySomeCriteriaAndUpdatedAtBefore(someField, dateTime, PageRequest.of(pageNum, 500)); // Spring Data Jpa page.get().forEach(errorRegister -> requestDispatcher.dispatch(errorRegister); // inside put to ThreadPoolTaskExecutor pageNum++; } while (page.hasNext()); }
Advertisement
Answer
The default ThreadPoolTaskScheduler
used by the @Scheduled
annotation is, according to the documentation, created with a single thread in the pool.
Assuming that you have not customised that thread pool then it’s not possible for your runRetry
method to be called by multiple threads at the same time.
If your runRetry
method is not thread safe then you should guard it anyway rather than relying on current default behaviour.