解決Spring Batch框架job任務只跑一次的問題
Spring Batch job任務只跑一次
在一次實際使用spring batch的過程中,在定時任務中,第一次執(zhí)行Job沒有出現問題,然后再次執(zhí)行時不會執(zhí)行job任務;
出現原因
針對這種異常需要明確Job Instance的概念,Job Instance 是由Job的名稱和執(zhí)行該job的參數組成的,當執(zhí)行Job時,會由于參數相同,會認為是同一個Job實例,如果該Job已經執(zhí)行過,就會報出異常。判斷Job是否執(zhí)行過的狀態(tài)是保存到Job Repository中的。
解決方法
為了使執(zhí)行參數不同,可以在參數中添加一個時間戳
JobParametersBuilder builder = new JobParametersBuilder(); builder.addDate("date", new Date());
job的啟動,停止,放棄
1、啟動一個job
運行一個批處理任務至少有兩點要求:一個 JobLauncher 和一個用來運行的 job 。它們都包含了相同或是不同的 context 。舉例來說,從命令行來啟動job,會為每一個job初始化一個JVM,因此每個job會有一個自己的 JobLauncher;從web容器的HttpRequest來啟動job,一般只是用一個 JobLauncher 來異步啟動job,http請求會調用這個 JobLauncher 來啟動它們需要的job。
通過web啟動job的例子:
@Controller public class JobLauncherController { @Autowired JobLauncher jobLauncher; @Autowired Job job; @RequestMapping("/jobLauncher.html") public void handle() throws Exception{ jobLauncher.run(job, new JobParameters()); } }
2、停止一個job
關閉不是立即發(fā)生的,因為沒有辦法將一個任務立刻強制停掉,尤其是當任務進行到開發(fā)人員自己的代碼段時,框架在此刻是無能為力的,比如某個業(yè)務邏輯處理。而一旦控制權還給了框架,它會立刻設置當前 StepExecution 為 BachStatus.STOPPED ,意為停止,然后保存,最后在完成前對JobExecution進行相同的操作。
Set<Long> executions = jobOperator.getRunningExecutions("sampleJob"); jobOperator.stop(executions.iterator().next());
或者在配置文件中實現:
它能夠讓job進行短暫的停留,以便操作員有時間進行其他的操作,stop元素必須配置restart屬性,當該job重新啟動的時候,需要手動觸發(fā),執(zhí)行step2。
<step id="step1" parent="s1"> <stop on="COMPLETED" restart="step2"/> </step> <step id="step2" parent="s2"/>
3、放棄一個job
一個job的執(zhí)行過程當執(zhí)行到FAILED狀態(tài)之后,如果它是可重啟的,它將會被重啟。如果任務的執(zhí)行過程狀態(tài)是ABANDONED,那么框架就不會重啟它。ABANDONED狀態(tài)也適用于執(zhí)行步驟,使得它們可以被跳過,即便是在一個可重啟的任務執(zhí)行之中:如果任務執(zhí)行過程中碰到在上一次執(zhí)行失敗后標記為ABANDONED的步驟,將會跳過該步驟直接到下一步(這是由任務流定義和執(zhí)行步驟的退出碼決定的)。
如果當前的系統(tǒng)進程死掉了(“kill -9”或系統(tǒng)錯誤),job自然也不會運行,但JobRepository是無法偵測到這個錯誤的,因為進程死掉之前沒有對它進行任何通知。你必須手動的告訴它,你知道任務已經失敗了還是說考慮放棄這個任務(設置它的狀態(tài)為FAILED或ABANDONED)-這是業(yè)務邏輯層的事情,無法做到自動決策。
只有在不可重啟的任務中才需要設置為FAILED狀態(tài),或者你知道重啟后數據還是有效的。Spring Batch Admin中有一系列工具JobService,用以取消正在進行執(zhí)行的任務。
4、失敗一個job
失敗的job是可以重新啟動的,因為它的狀態(tài)是FAILED,如果step2失敗,則返回一個EARLY TERMINATION的返回碼,step3也就不會執(zhí)行。否則繼續(xù)執(zhí)行step3
<step id="step1" parent="s1" next="step2"> <step id="step2" parent="s2"> <fail on="FAILED" exit-code="EARLY TERMINATION"/> <next on="*" to="step3"/> </step> <step id="step3" parent="s3">
5、結束一個job
已經結束的job是不能重新啟動的,因為它的狀態(tài)是COMPLETED。如果step2失敗了,則step3就不執(zhí)行了,該job也就COMPLETED,結束了。如果step2成功了,則繼續(xù)往下執(zhí)行step3。
<step id="step1" parent="s1" next="step2"> <step id="step2" parent="s2"> <end on="FAILED"/> <next on="*" to="step3"/> </step> <step id="step3" parent="s3">
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringBoot高級配置之臨時屬性、配置文件、日志、多環(huán)境配置詳解
這篇文章主要介紹了SpringBoot高級配置之臨時屬性、配置文件、日志、多環(huán)境配置,本文結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02在Mac下IDEA安裝并使用protobuf方式(Java)
這篇文章主要介紹了在Mac下IDEA安裝并使用protobuf方式(Java),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11Java計算一個數加上100是完全平方數,加上168還是完全平方數
這篇文章主要介紹了Java計算一個數加上100是完全平方數,加上168還是完全平方數,需要的朋友可以參考下2017-02-02使用mybatis-plus分頁出現兩個Limit的問題解決
在使用MyBatis-Plus進行分頁查詢時,可能會遇到查詢SQL中出現兩個limit語句的問題,這通常是由于在多個模塊中重復引入了MyBatis-Plus的分頁插件所導致的,下面就來介紹一下如何解決,感興趣的可以了解一下2024-10-10