当前位置: 首页 > 知识库问答 >
问题:

Spring批处理程序看不到更新的数据

谭勇
2023-03-14

我使用的是Spring Batch 3.0.7、EclipseLink 2.6.4和Oracle 11/12。

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

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

处理器是一个使用Spring Data JpaRepository的项目处理器,并将数据添加到父库中。Repository具有@Transactional(只读=true)

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

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

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

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

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

更新:在这里你可以找到代码的框架https://github.com/th-e/SpringBatchDataPump

共有1个答案

秦信瑞
2023-03-14

您需要了解事务包装了read-处理-写入序列。因此,如果之间发生其他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>

例如,如果您不介意进行脏读,您可以将隔离更改为READ_UNCOMMITTED

另一个解决方案:您可以配置spring batch提供的重试机制:

<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>
 类似资料:
  • 我需要依次执行七个不同的流程(一个接一个)。数据存储在Mysql中。我正在考虑以下选项,如果我错了,或者有更好的解决方案,请纠正我。 要求: > 需要分块处理数据。 我的解决方案和问题:数据读取: 使用JdbcCursorItemReader读取数据,因为这是性能最好的db阅读器-但是,SQL非常复杂,所以我可能不得不考虑使用JdbcTemboard的自定义ItemReader?这让我在处理数据时

  • 我有一个批处理过程,它正在为一组实体重新计算数据。通过Hibernate从DB获取实体列表: 当流程运行时,某些实体似乎正在分离,导致两种症状: 当尝试获取惰性数据时,我得到一个异常: 在我的第一次尝试中,我试图通过调用inside

  • 问题内容: 我有一个dao,它基本上使用hibernate将记录插入到一​​个表中,该dao用标记为注释,并且我有一个服务,该服务会生成其他一些东西,然后调用我的dao。我的服务也标注了使用。 我叫服务循环。我在dao上的插入内容是否可以批量或一个接一个地工作?我如何确定它们可以批量工作?hibernateTransaction Manager是否管理批处理插入? 我正在使用Oracle DB。

  • 我使用的是Spring Batch 2.1.8。释放我有一个文件,它由一些头信息和一些需要处理的记录组成。 我有一个使用面向块处理的步骤。该步骤包含ItemReader和ItemWriter的实现。ItemReader实现是线程安全的,而ItemWriter不是。 我想在处理(或写入)任何记录之前使用标题信息。在继续使用面向块的处理时,如何确保这一点? 建议的解决方案:一种解决方案可以是编写一个预

  • 当应用程序在单个实例中运行时也是如此。 有人可以帮助如果有任何额外的步骤,我必须介绍更新步骤和工作完成?

  • 我正在使用STS 2.81附带的Spring Batch模板和Manning的Spring Batch in Action中的示例创建一个Spring Batch作业。我可以毫无问题地执行块读取器和写入器,但我的代码跳过了处理器。我甚至尝试过在处理器中取消所有对象,但什么也没有,对象仍然设法被写入,就像处理器被忽略一样。我尝试在处理器中调用system.out.println,但没有在终端中打印出