2017-08-16 75 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 –

相关问题