事務模型描述
1、step之間事務獨立
2、step划分成多個chunk執行,chunk事務彼此獨立,互不影響;chunk開始開啟一個事務,正常結束提交。chunk表示給定數量的item的操作集合,主要屬性commit-interval,表示數量達到多少條提交一次。

圖-job總體事務

圖-step內部事務
3、chunk定義:默認設置commitInterval=N,即讀取N條數據為一個chunk(采用默認SimpleCompletionPolicy),或者reader里面所讀取的item==null,或者滿足自定義完成策略
事務提交&回滾
1、事務必須添加<batch:tasklet>標記,它表示step的一個事務過程,包含事務的重啟,同步,異步,並發等策略。
1、事務提交條件:chunk執行正常,未拋RuntimeExecption
2、默認情況下,Reader、Processor、Writer拋出未捕獲RuntimeException,當前chunk事務回滾,step失敗,job失敗
3、通過以下配置,保證出現異常時,事務不回滾,事務繼續提交:
<batch:tasklet>
<batch:chunk />
<batch:no-rollback-exception-classes>
<batch:include class="com.xx.batch.DefRuntimeException"/>
</batch:no-rollback-exception-classes>
</batch:tasklet>
4、事務配置.通過以下配置,改變事務行為
<batch:tasklet>
<batch:transaction-attributes isolation="READ_COMMITTED" propagation="REQUIRES_NEW" timeout="300"/>
<batch:chunk reader="defItemReader" processor="defItemProcessor" writer="defItemWriter" commit-interval="10"/>
</batch:tasklet>
默認配置:
DEFAULT+REQUIRED
參數配置影響
1、任務恢復
<batch:job id="jobId" restartable="true">
</batch:job>
通過配置job的restartable=true,保證任務失敗后能夠進行恢復。比如:文件處理時,chunkSize=10,在line=35時處理失敗,文件修復后,job將從31行開始重新處理(因為1-10,11-20,21-30進行事務提交,Spring Batch將ExecutionContext中的count持久化到系統表,恢復時讀取)
FlatFileItemReader繼承AbstractItemCountingItemStreamItemReader類,所以默認具備讀取恢復能力
2、跳過
<batch:chunk skip-limit="20">
<batch:skippable-exception-classes>
<batch:include class="com.xx.batch.ExceptionClass" />
</batch:skippable-exception-classes>
</batch:chunk>
或者
<batch:chunk skip-policy="defSkipPolicy">
</batch:chunk>
跳過數據量或者跳過策略不滿足時候,step失敗,job失敗
a、ItemProcessor處理中跳過
事務回滾,失敗條目在緩存標志為跳過,並重新開啟一個事務處理緩存中的條目,並提交。這個時候會重復process,如果存在業務邏輯,注意冪等性問題
b、ItemWriter處理中跳過
事務回滾,失敗條目在緩存標志為跳過,因為是批量提交,需要找出問題條目,所以針對每個條目開啟一個事務循環處理process&write並提交,如果存在業務邏輯,注意冪等性問題
3、重試
<batch:chunk retry-limit="20">
<batch:retryable-exception-classes>
<batch:include class="com.xx.batch.ExceptionClass" />
</batch:retryable-exception-classes>
</batch:chunk>
或者
<batch:chunk retry-policy="defRetryPolicy">
</batch:chunk>
重試次數達到或者重試策略不滿足時,step失敗,job失敗
4、reader-transactional-queue&processor-transactional
a、reader-transactional-queue,默認false,設置為true代表read資源具備事務特性,chunk事務回滾時,資源回滾。出現異常導致重復讀取並處理,注意冪等性問題
b、processor-transactional,默認true,即writer失敗時,processor重復執行,需要注意冪等性問題;設置false,即writer失敗時,processor不再執行
處理組件事務
Spring Batch提供了很多監聽器等組件,在處理事務相關的問題時,參考下圖進行事務考慮:

圖-job執行階段軌跡&事務
注意:ItemReadeListener、ItemProcessListener、ItemWriteListener所有監聽方法均在chunk事務當中執行,所以,如果在這些監聽方法里面要處理好業務事務與chunk事務的關系,最好將業務事務設置為獨立REQUIRE_NEW特性,避免相互影響
關於onXXError監聽方法:改監聽方法在事務回滾之前執行,或者事務提交之前執行(如果有no-rollback-exception配置)
一點點建議
在使用Spring Batch的時候需要注意它要解決的問題域,它本身的關注點應該是提供一個批量處理的能力,即對文件或數據庫的批量讀取、寫入和協議數據的轉換,以及對整個過程的控制。
因此,如果在批量處理過程中需要做些業務邏輯,那么業務邏輯的實現需要與它彼此獨立,盡量不要在batch的處理過程中耦合業務邏輯,原因如下:
a、Spring Batch的使用目的更加清晰
b、避免Spring Batch事務與業務邏輯事務的交叉耦合所帶來的偶發復雜性,應用已於理解
其次,Spring Batch的系統表最好和業務數據表處於同一物理庫,保證事務的一致性