2017-08-16 31 views
2

我使用Spring Batch 3.0.7,EclipseLink 2.6.4和Oracle 11/12。Spring批處理器沒有看到更新的數據

我在數據庫中有一對多的關係。批處理讀取器讀取處理器讀取多邊(子)的一邊(父)。 我很確定這兩個都是由不同的應用程序事務插入的。

批處理讀取器來自JdbcCursorItemReader,只是設置了rowMapperpreparedStatementSetter

處理器是使用Spring Data JpaRepository的ItemProcessor並將數據添加到父級。 資源庫有@Transactional(readOnly = true)

閱讀器似乎總是使用相同的數據庫會話,並且處理器始終使用不同的數據庫會話。

有了這個設置,我不時得到一個ORA-01555(快照太舊)錯誤。 但是還有一個更大的問題: 如果在作業運行之間存在新的父子數據,則閱讀器找到父代,但處理器沒有看到任何子代。 只有第一個父/子插入工作(以某種方式,處理器停留在Oracle數據的修復快照上)。

我已經做了什麼來解決這個問題:每個作業運行我都要關閉Spring Context,然後重新創建它。 這解決了這兩個問題(ORA-01555錯誤和處理器沒有看到更新的數據)。

重新創建Spring上下文的目的是獲取新的數據庫會話。我不知道這樣做的更簡單的方法。

我認爲不應該有必要重新創建上下文,但我找不到這種行爲的原因。

UPDATE: 在這裏你可以找到的代碼 https://github.com/th-e/SpringBatchDataPump

+0

添加一些代碼和配置沒有它的問題是很難看到的。關閉並重新創建環境也是一個壞主意。 –

+0

重新創建上下文只是爲了儘快修復。但有趣的是,它解決了這兩個問題。更多細節即將到來...... –

回答

0

您需要了解該交易的骨架包裹read-process-write序列。所以如果其他數據庫寫入會發生 - 這個事務將會失敗。

閱讀器似乎總是使用相同的數據庫會話,並且 處理器始終使用不同的數據庫會話。

這是奇怪的說法,如果您確定這是真的,那麼您必須再次檢查您的配置。它不應該是這樣。

您可以檢查您的交易屬性。

<batch:tasklet> 
     <batch:transaction-attributes isolation="READ_COMMITTED" propagation="REQUIRES_NEW" timeout="200"/> 
     <batch:chunk reader="myItemReader" writer="myItemWriter" commit-interval="20"/> 
    </batch:tasklet> 

舉例來說,如果你不介意有髒讀 - 你可以改變隔離READ_UNCOMMITTED

另一種解決方案:您可以配置彈簧批量提供重試機制:

<batch:tasklet> 
    <batch:chunk reader="myItemReader" writer="myItemWriter" commit-interval="20" retry-limit="15"> 
    <batch:retryable-exception-classes> 
     <batch:include class="com.stackoverflow.MyRetryableException" /> 
    </batch:retryable-exception-classes> 
    </batch:chunk> 
</batch:tasklet> 
+0

本週我會盡量提供一個簡單的例子。 –

+0

以下是代碼的框架:https://github.com/th-e/SpringBatchDataPump –

相關問題