2013-04-14 165 views
0

我需要連續執行七個不同的進程(一個接一個地執行)。數據存儲在Mysql中。我正在考慮以下選項,如果我錯了,請糾正我,或者如果有更好的解決方案。彈簧批次 - 處理器鏈

質量要求:

  1. 閱讀從數據庫中的數據,執行七道工序最後,寫入處理數據到數據庫(資料驗證,計算1,calculation2 ...等)。

  2. 需要處理塊中的數據。

我的解決方案和問題: 數據讀取:

  1. 閱讀使用JdbcCursorItemReader的數據,因爲這是表現最好的分貝讀者 - 但是,在SQL是非常複雜的,所以我可能要考慮一個使用JdbcTemplate的自定義ItemReader?這使我在處理數據時具有更大的靈活性。

過程:

  1. 定義七個步驟和組塊,使用共享公司Databean步驟之間的數據。但是,這不是一個好主意,因爲數據處理塊和step1編寫器的每個塊之後都會在databean中創建一組新的數據。當這個databean與其他步驟共享時,數據完整性將成爲一個問題。

  2. 使用StepExecutionContext在步驟之間共享數據。但這可能會影響性能,因爲這涉及批處理作業存儲庫。

  3. 定義只有一個步驟,一個ItemReader和一個進程鏈(七個進程),並創建一個ItemWriter,將處理後的數據寫入數據庫。但是,我將無法管理或監控每個不同的流程,所有這些都將一步到位。

回答

4

org.springframework.batch.item.support.CompositeItemProcessor是會支持你的要求類似於你的第二個選項,Spring Batch的框架的開箱即用的組件。這可以讓你做到以下幾點; - 保持設計/解決方案與數據庫中的讀數分離(itemreader) - 保持每個處理器的關注點與配置的分離 - 允許任何單獨的處理器通過返回null來關閉該塊,而不考慮先前的過程

CompositeItemProcessor遍歷代表循環,因此它與動作模式「相似」。它在你描述的情況下非常有用,仍然可以讓你充分利用組塊的好處(異常,重試,提交政策等)

+0

感謝您的回覆。 – Nandan

+0

在管理方面,哪種方式最適合?獨立的步驟或一步與compositeItemProcessor? – Nandan

+0

單獨的步驟會在故障情況下重新啓動時引入複雜性。使用CompositeItemProcessor的單個步驟意味着所有的處理器在出現故障時都會回滾。 –

1

建議:

1)請閱讀使用JdbcCursorItemReader數據。

所有開箱即用的組件都是不錯的選擇,因爲它們已經實現了使您的步驟可重新啓動的ItemStream接口。但就像你提到的那樣,有時候,請求只是爲了複雜,或者像我一樣,你已經有了一個可以重用的服務或DAO。

我建議你使用ItemReaderAdapter。它讓你配置一個委託服務來調用來獲取你的數據。

<bean id="MyReader" class="xxx.adapters.MyItemReaderAdapter"> 
     <property name="targetObject" ref="AnExistingDao" /> 
     <property name="targetMethod" value="next" />   
    </bean> 

注意,targetMethod必須尊重ItemReaders的讀合同(當沒有更多的數據返回NULL)

如果你的工作並不需要被重新啓動,你可以簡單地使用類:組織。 springframework.batch.item.adapter.ItemReaderAdapter

但是如果你需要你的工作是重新啓動,你可以這樣創建自己的ItemReaderAdapter:

public class MyItemReaderAdapter<T> extends AbstractMethodInvokingDelegator<T> implements ItemReader<T>, ItemStream { 




private long currentCount = 0; 

private final String CONTEXT_COUNT_KEY = "count"; 

/** 
* @return return value of the target method. 
*/ 
public T read() throws Exception { 

    super.setArguments(new Long[]{currentCount++}); 
    return invokeDelegateMethod(); 
} 
@Override 
public void open(ExecutionContext executionContext) 
     throws ItemStreamException { 
    currentCount = executionContext.getLong(CONTEXT_COUNT_KEY,0); 

} 


@Override 
public void update(ExecutionContext executionContext) throws ItemStreamException { 
    executionContext.putLong(CONTEXT_COUNT_KEY, currentCount); 
    log.info("Update Stream current count : " + currentCount); 
} 


@Override 
public void close() throws ItemStreamException { 
    // TODO Auto-generated method stub 

} 

} 

由於開箱即用的itemReaderAdapter不可重新啓動,您只需創建自己的實現ItemStream的步驟

2)關於7步vs 1步。

我會用compositeProcessor在這一步上1步。 7步選項只會帶來IMO的問題。

1)7步databean:所以你的作家提交數據庫直到第7步..然後第7步作家試圖承諾真正的數據庫和繁榮錯誤!全部丟失,並且批次必須從步驟1重新開始!

2)使用上下文的7個步驟:可能會更好,因爲您將在spring批處理元數據中保存狀態..但在springBatch的元數據中存儲大數據並不是一個好習慣!

3)是國際海事組織的方式。 ;-)