我試圖解決最近困擾我們的系統的Spring批處理問題。我們有一份工作,大部分工作很好。這是一個下載和處理數據的多步驟工作。Spring批處理步驟不執行
問題是有時候這項工作會被炸燬。也許我們嘗試連接的服務器會引發錯誤,或者我們在作業中關閉了服務器。此時,我們的石英調度程序下次嘗試運行作業它似乎沒有做任何事情。以下是該作業定義的刪節版:
<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
。我在tasklet中設置了一個斷點,它永遠不會進入它的內部。
如果我清除存儲在我們的mysql數據庫中的所有spring批處理表,並重新啓動服務器,它將重新開始工作,但我寧願明白什麼阻止它在此時正確運行比採用焦土戰術讓工作順利進行。
我是Spring批處理的新手,說得很溫和,所以如果我省略了重要的細節,請原諒我。我設置了斷點並開啓了日誌記錄,以瞭解我所能做到的。
我到目前爲止觀察到的情況是,條目似乎不再寫入BATCH_STEP_EXECUTION和BATCH_JOB_EXECUTION表。
有作業沒有BATCH_JOB_EXECUTION項不在完成的狀態和未在已完成
你會看到有一批沒有BATCH_STEP_EXECUTION條目:驗證定義,我已經證實,春天批處理調用驗證器併成功完成(設置斷點並逐步完成)。第一步不會被執行。
loggingContextJobListener和loggingContextStepListener都不會觸發。什麼可能導致這個?
UPDATE 我仔細看了一下downloadListener
添加爲批處理:listener。下面是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表可以有效地確保您獲得新的Job實例,因爲之前使用過哪些Params的記錄已經消失。 –
可能值得在'JobParameters'和Spring Batch的可重啓性上進行研究,以獲得概念背後的更多上下文:https://docs.spring.io/spring-batch/reference/html/configureJob.html#restartability –