2016-05-05 148 views
1

我試圖解決最近困擾我們的系統的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被刪除,我該如何刪除它們?

回答

2

JobParametersValidator,在您的情況下,downloadValidator bean在作業開始前運行。

你的情況發生了什麼是你通過這項工作的參數與「炸燬」JobInstance相同。但是,由於這項工作戲劇性地失敗了,它可能沒有陷入失敗狀態。

您可以使用不同的參數運行作業(以獲取新的作業實例),或者在重新啓動之前嘗試將之前步驟/作業的狀態更新爲BATCH_STEP_EXECUTION或BATCH_JOB_EXECUTION中的FAILED狀態。

UPDATE(新信息已添加到問題) 您必須謹慎處理您的工作流程。是的,您的步驟失敗了,但是您的上下文文件指示該作業的END(完整)不在CONTINUE之內。

<batch:next on="CONTINUE" to="job.download-stuff.process-stuff.step" /> 
<batch:end on="*" /> 

首先,要非常小心地在*上結束。在您的情況下,這會導致您完成工作(成功完成)FAILEDExitCode。此外,成功執行的默認ExitCodeCOMPLETED,而不是CONTINUE,因此請小心。

<!-- nothing to me indicates you'd get CONTINUE here, so I changed it --> 
<batch:next on="COMPLETED" to="job.download-stuff.process-stuff.step" /> 

<!-- if you ever have reason to stop here --> 
<batch:end on="END" /> 

<!-- always fail on anything unexpected --> 
<batch:fail on="*" /> 
+0

你提到JobParametersValidator前跑」這項工作開始了「。你是說這不是正確的行爲?我注意到刪除BATCH_JOB_EXECUTION_PARAMS是使作業再次在本地運行所需的全部 – IcedDante

+0

這是預期的行爲。在任何事情發生之前(如插入到BATCH_JOB_INSTANCE),評估作業參數的有效性。清除BATCH_JOB_EXECUTION_PARAMS表可以有效地確保您獲得新的Job實例,因爲之前使用過哪些Params的記錄已經消失。 –

+1

可能值得在'JobParameters'和Spring Batch的可重啓性上進行研究,以獲得概念背後的更多上下文:https://docs.spring.io/spring-batch/reference/html/configureJob.html#restartability –

0

有同樣的問題,在測試/調試過程中,我不停地作業名稱和參數不變,確保要更改作業名稱或作業參數,以獲得不同的JobExecution

相關問題