Почему может не срабатывать триггер если вместо периодичности использую запуск по расписанию?

Приложение на spring boot 2 с планировщиком Quartz, база данных Oracle

У меня есть job, которая просто распечатывает сообщение. Есть так же TactConfig класс, где настроены details, trigger, scheduler

У меня возникла следующая проблема с триггером, если при его создании я использую периоды, например

.withSchedule(simpleSchedule().repeatForever().withIntervalInSeconds(5))

то в логах вижу сообщения каждые 5 секунд, с этим все ок.

Но, если я пытаюсь использовать расписания

.withSchedule(CronScheduleBuilder.cronSchedule(TIME))

То сообщения либо вообще не отображаются, или отображаются 1 или 2 раза после старта и все.

Я использую синхронизацию инстансов через базу данных. В sheduler удаляю джобы потому, что при старте приложение ругает что такая джоба уже существует и я удаляю прежнюю чтобы подменить расписание если я его меняю.

Мой класс с бинами:

@Configuration
public class TactConfig {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private final String QRTZ_TRIGGER = "QRTZ_TACT_TRIGGER";
    private final String QRTZ_GROUP = "QRTZ_TACT_GROUP";
    private final String QRTZ_JOB = "TACT_JOB";
    private final String TIME = "0 0-59 0-23 * * ?"; /* every second an hour */

    @Bean
    public JobDetail tactJobDetail() {
        return JobBuilder
                .newJob(TactJob.class)
                .storeDurably(true)
                .requestRecovery(true)
                .withIdentity(new JobKey(QRTZ_JOB, QRTZ_GROUP))
                .build();
    }

    @Bean
    public Trigger tactTrigger() {
        return TriggerBuilder
                .newTrigger()
                .withIdentity(new TriggerKey(QRTZ_TRIGGER, QRTZ_GROUP))
                .withSchedule(CronScheduleBuilder.cronSchedule(TIME))                     /*this doesn't work*/
//                .withSchedule(simpleSchedule().repeatForever().withIntervalInSeconds(5))  this works okey
                .build();
    }

    @Bean
    public Scheduler scheduler(Trigger trigger, JobDetail job, SchedulerFactoryBean factory)
            throws SchedulerException {
        Scheduler scheduler = factory.getScheduler();
        if (scheduler.checkExists(job.getKey())){
            scheduler.deleteJob(job.getKey());
        }
        scheduler.scheduleJob(job, trigger);
        scheduler.start();
        return scheduler;
    }
}

Сама Джоба

@DisallowConcurrentExecution 
@PersistJobDataAfterExecution
public class TactJob implements Job { 
  private static final String MESSAGE = "================MY MESSAGE===================";
  private Logger logger = LoggerFactory.getLogger(getClass());

  @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { 
    logger.info(MESSAGE); 
  } 
}
  • Пробовал удалять аннотацию @DisallowConcurrentExecution из джобы
  • Пробовал подкостылить вот так
@Bean
  public Trigger tactTrigger(JobDetail tactJobDetail) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        Assert.isTrue(CronExpression.isValidExpression(TIME), format("некорректно задано расписания для %s", QRTZ_JOB));

        return TriggerBuilder
                .newTrigger()
                .startAt(calendar.getTime())
                .startNow()
                .withIdentity(new TriggerKey(QRTZ_TRIGGER, QRTZ_GROUP))
                .withSchedule(cronSchedule(new CronExpression(TIME)))
//                .withSchedule(simpleSchedule().repeatForever().withIntervalInSeconds(5))
                .build();
    }

Находил на хабре статью и там был такой костыль, но это не помогло Что можно еще попробовать, мне нужно запускать задачу по расписанию только на одном инстансе за раз, иначе можно было бы воспользоваться @Scheduler

Заметил так же такую вещь что при таком формате времени, все отрабатывает - событие происходит раз в 5 секунд

private final String TIME = "0/5 * * ? * * *";

А вот такой формат срабатывает только единожды, а должен каждую минуту

private final String TIME = "0 * * ? * * *";

Ответы (0 шт):