Java Spring批处理器不支持';看不到更新的数据

Java Spring批处理器不支持';看不到更新的数据,java,spring,spring-batch,Java,Spring,Spring Batch,我使用的是SpringBatch 3.0.7、EclipseLink 2.6.4和Oracle 11/12 我在数据库中有一对多关系。批处理读取器读取单侧(父级),处理器读取多侧(子级)。 我很确定这两个都是由不同的应用程序以事务方式插入的 批处理读取器源自JdbcCursorItemReader,只需设置rowMapper和preparedStatementSetter 处理器是一个使用Spring Data JpaRepository的ItemProcessor,并将数据添加到父级。 存储库

我使用的是SpringBatch 3.0.7、EclipseLink 2.6.4和Oracle 11/12

我在数据库中有一对多关系。批处理读取器读取单侧(父级),处理器读取多侧(子级)。 我很确定这两个都是由不同的应用程序以事务方式插入的

批处理读取器源自
JdbcCursorItemReader
,只需设置
rowMapper
preparedStatementSetter

处理器是一个使用Spring Data JpaRepository的
ItemProcessor
,并将数据添加到父级。 存储库具有
@Transactional(readOnly=true)

读卡器似乎总是使用相同的数据库会话,而处理器总是使用不同的数据库会话

通过此设置,我不时会遇到
ORA-01555
(快照太旧)错误。 但还有一个更大的问题: 如果在作业运行之间有新的父-子数据,则读取器会找到父数据,但处理器不会看到任何子数据。 只有第一个父/子插入起作用(在某种程度上,处理器停留在Oracle数据的修复快照上)

我为解决此问题所做的工作: 在每次作业运行时,我都关闭Spring上下文,然后重新创建它。 这解决了这两个问题(
ORA-01555
错误和处理器看不到更新的数据)

重新创建Spring上下文的目的是获取新的数据库会话。我不知道有什么更简单的方法可以做到这一点

我认为没有必要重新创建上下文,但我找不到这种行为的原因

更新: 在这里您可以找到代码的框架

您需要了解事务包装
读取过程写入
顺序。因此,如果在这段时间内发生其他db写操作,则此事务将失败

读卡器似乎总是使用相同的数据库会话和 处理器始终使用不同的数据库会话

这是一个奇怪的说法,如果您确信这是真的,那么您必须再次检查您的配置。事实不应该如此

您可以检查事务属性

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

在问题中添加一些代码和配置,否则很难看到。关闭并重新创建上下文也是一个坏主意。重新创建上下文只是为了尽快修复。但有趣的是,它解决了这两个问题。更多的细节即将到来……本周我将尝试提供一个最小的示例。
<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>