Spring batch 2.1.8 Запуск одного экземпляра задания, когда срабатывает триггерный кварцевый крон - PullRequest
2 голосов
/ 16 декабря 2011

У меня настроен пружинный кварц. У меня есть две работы, настроенные и работающие параллельно. Задания читают файл, а затем записывают некоторые данные в базу данных. Здесь есть сложная часть, имена файлов вычисляются в методе beforeJob () моего слушателя выполнения. После завершения каждого задания afterJob () рассчитывает следующее имя файла. Имена файлов имеют следующий шаблон xxxxxx.nnnn, где nn .. - числа, и иногда в последовательности могут отсутствовать числа, поэтому я пытаюсь «перепрыгнуть» через пропущенные фрагменты и найти существующее число для запуска задания.
Я хочу знать, возможно ли ограничить количество заданий, запускаемых при каждом срабатывании триггера cron? Я хочу запустить единственную работу после срабатывания триггера хрон.

Например:

  1. В 12:30 работа запускается.
  2. Задание пытается найти правильный файл
  3. Задание не выполняется с FileNotFound (который настроен как исключение, не допускающее пропуска)
  4. После выполнения задания счетчик fileName увеличивается

Прямо сейчас, когда срабатывает триггер, я получаю около 4 или более заданий одного типа, выполняемых асинхронно. В моей пакетной настройке у меня есть два <jobs>, настроенные на запуск один за другим каждый час с интервалом 5 минут друг от друга. Обе работы выполняют поток, представленный в примере. В заключение: возможно ли запустить одно задание после срабатывания триггера cron и запустить оба типа заданий параллельно.

Peter

1 Ответ

4 голосов
/ 03 января 2012

Ваша работа должна знать, какой файл обрабатывать, прежде чем он будет выполнен.Например, имя файла должно быть передано в качестве параметра задания.Удалите JobExecutionListener и добавьте StepExecutionListener для доступа к параметрам задания через StepExecution#getJobParameters().Одно задание = один файл.

Теперь из вашего планировщика вы хотите убедиться, что в один момент времени выполняется только одно задание.Вы можете достичь этого двумя способами:

• Использование исполнителя асинхронных задач.В этом случае каждый раз, когда вы запускаете задание, оно не будет выполняться в фоновом режиме (если ваш планировщик не запускает события таймера каждый раз в новом потоке).

<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
    <property name="taskExecutor" ref="taskExecutor" />
</bean>

<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" />

• Если вы используете одно и то же заданиедля запуска других заданий, которые должны выполняться в фоновом режиме, вам нужно использовать ThreadPoolTaskExecutor, но вы можете вручную проверить, выполняется ли задание:

for (final JobInstance jobInstance : jobExplorer.getJobInstances(jobName(), 0, LOOK_BEHIND_INSTANCES)) {
    for (final JobExecution jobExecution : jobExplorer.getJobExecutions(jobInstance)) {
        final BatchStatus status = jobExecution.getStatus();

        if (status.isRunning()) {
            // Ops:
            break;
        }
    }
}
...