Я пытаюсь исправить проблему в Spring Batch, которая недавно преследовала нашу систему. У нас есть работа, которая по большей части прекрасно работает. Это многоступенчатое задание, которое загружает и обрабатывает данные.Spring Batch Step не выполняется
Проблема в том, что иногда работа будет бомбить. Возможно, сервер, к которому мы пытаемся подключиться, выдает ошибку или мы закрываем сервер в середине задания. В этот момент в следующий раз, когда наш кварцевый планировщик пытается запустить задание , он ничего не делает. Ниже приводится сокращенный вариант этого определения задания:
<batch:job id="job.download-stuff" restartable="true">
<batch:validator ref="downloadValidator"/>
<batch:step id="job.download-stuff.download">
<batch:tasklet ref="salesChannelOrderDownloader" transaction-manager="transactionManager">
<batch:transaction-attributes isolation="READ_UNCOMMITTED" propagation="NOT_SUPPORTED"/>
<batch:listeners>
<batch:listener ref="downloadListener"/>
<batch:listener ref="loggingContextStepListener" />
</batch:listeners>
</batch:tasklet>
<batch:next on="CONTINUE" to="job.download-stuff.process-stuff.step" />
<batch:end on="*" />
</batch:step>
<batch:step id="job.download-stuff.process-stuff.step">
...
</batch:step>
<batch:listeners>
<batch:listener ref="loggingContextJobListener"/>
</batch:listeners>
После того, как он попадает в это состояние, то downloadValidator
работает, но он никогда не делает его на первую стадию download-stuff.download
. Я установил точку останова в таскеле, и она никогда не делает ее внутри.
Если я удалю все таблицы весеннего пакета, которые хранятся в нашей базе данных mysql, и перезапустите сервер, он снова начнет работать, но я бы лучше понял, что мешает ему корректно работать на этом этапе чем использовать тактику выжженной земли, чтобы заставить работу работать.
Я новичок в Spring Batch, мягко говоря, так что простите меня, если я опускаю важные детали. Я установил контрольные точки и включил регистрацию, чтобы узнать, что смогу.
То, что я наблюдал до того, как пройти через базу данных, состоит в том, что записи больше не записываются в таблицы BATCH_STEP_EXECUTION и BATCH_JOB_EXECUTION.
Там нет записей BATCH_JOB_EXECUTION для работы, которые не в состоянии ЗАВЕРШЕНА и нет записей BATCH_STEP_EXECUTION, которые не в ВЫПОЛНЕНО
Вы увидите, что есть партия: валидатор определена, я подтвердил, что весной пакетный вызов этого валидатора и его успешное завершение (установка точки останова и переход через нее). Первый шаг не выполняется.
Ни один из журналовContextJobListener или loggingContextStepListener, похоже, не срабатывает. Что может быть причиной этого?
UPDATE Я присмотрелся на downloadListener
добавленного в пакетном режиме: слушатель. Вот исходный код Afterstep:
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public ExitStatus afterStep(StepExecution stepExecution) {
long runSeconds = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - nanoStart);
// If Success - we're good
if (stepExecution.getStatus() == BatchStatus.COMPLETED) {
Long endTs = stepExecution.getExecutionContext().getLong("toTime");
Date toTime = new Date(endTs);
handleSuccess(toTime, stepExecution.getWriteCount());
return null;
}
// Otherwise - record errors
List<Throwable> failures = stepExecution.getFailureExceptions();
handleError(failures);
return ExitStatus.FAILED;
}
Я подтвердил, что return ExitStatus.FAILED
линия выполняет и исключение, которое было брошено регистрируется в failureExceptions. Похоже, что когда-то это происходит, запись BATCH_JOB_EXECUTION находится в состоянии COMPLETED (и exit_code), и STEP_EXECUTION не работает.
На этом этапе записи в таблице BATCH_JOB_EXECUTION_PARAMS остаются. Я действительно пытался изменить значения своих столбцов KEY_NAME и значений, но это все еще не позволяло заданию работать. Пока есть параметры, привязанные к JOB_EXECUTION_ID, другое задание, принадлежащее одному BATCH_JOB_INSTANCE, не может работать.
После того, как я удалить записи в BATCH_JOB_EXECUTION_PARAMS для конкретного JOB_EXECUTION_ID, другой BATCH_JOB_EXECUTION может работать, даже если все записи BATCH_JOB_EXECUTION находятся в завершенном состоянии.
Итак, у меня есть два вопроса - это правильное поведение? И если да, то что мешает удалению BATCH_JOB_EXECUTION_PARAMS и как их удалить?
Вы упомянули, что JobParametersValidator побежал «перед работа начинается ». Вы говорите, что это не правильное поведение? Я замечаю, что удаление BATCH_JOB_EXECUTION_PARAMS - это все, что необходимо для повторного запуска задания – IcedDante
Это ожидаемое поведение. Параметры работы оцениваются для достоверности прежде, чем что-либо еще произойдет (например, вставки в BATCH_JOB_INSTANCE). Вычистка таблицы BATCH_JOB_EXECUTION_PARAMS эффективно обеспечила получение нового экземпляра задания, поскольку запись, в которой ранее использовались Params, исчезла. –
Скорее всего, стоит разобраться в перезапусках JobParameters и Spring Batch, чтобы получить еще один контекст за концепциями: https://docs.spring.io/spring-batch/reference/html/configureJob.html#restartability –