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

用JPA事务处理Spring批处理错误

路思源
2023-03-14

在happy path场景中,我有一个spring批处理工作,但现在我将重点放在错误处理上。

.faultTolerant()
    .skip(SkippableException.class)
    .skip(FlatFileParseException.class)
    .skipLimit(Integer.MAX_VALUE)
    .retryLimit(0)

但是,在另一个测试中,我想证明一个不可预见的数据库错误会导致作业失败。为此,我创建了一个触发器,该触发器会导致对要插入的表的插入失败。

这似乎起作用了,在writer执行之后,在事务提交期间抛出异常,并且我得到以下日志消息:

    2019-11-14 16:12:15.183 ERROR 88508 --- [           main] o.h.i.ExceptionMapperStandardImpl        : HHH000346: Error during managed flush [org.hibernate.exception.GenericJDBCException: could not execute statement]
    2019-11-14 16:12:15.184  INFO 88508 --- [           main] o.s.batch.core.step.tasklet.TaskletStep  : Commit failed while step execution data was already updated. Reverting to old version.

这似乎也是预期的行为。问题是,这并不能阻止工作。该步骤退出到SimplyRetryExceptionHandler,它似乎认为异常不是致命的。它“重试”该块,并将其标记为成功,然后作为成功完成继续前进。

共有1个答案

尉迟兴修
2023-03-14

在我自己的读取器/处理器/写入器代码中没有抛出异常,这似乎是一个问题,因为sql语句直到事务试图提交时才执行。

解决办法是将我的EntityManager注入到我的writer中,并手动调用flush(),这也可以在spring batches JpaItemWriter中看到。这将强制从我的代码中抛出任何sql异常,我的容错步骤将按预期处理这些异常。

 类似资料:
  • 我有以下步骤:

  • 我使用FlatFileItemReader创建了一个spring批处理作业,它从一个分隔文件中读取数据,然后使用JdbcBatchItemWriter写入DB。我的setp配置如下所示。 上面的配置是为每100行打开单独的事务,因此,如果在完成tasklet(步骤1)之前发生故障,则我无法恢复之前提交的行。有没有办法在一个事务中运行整个tasklet?。 另外:我使用MapJobRepositor

  • 我开始学习spring batch,遇到一个问题,当我想使用在数据库中持久化作业的状态时。编译器显示: “原因:org.springframework.beans.factory.beanCreationException:创建类路径资源[springconfig.xml]中定义的名为'job repository'的bean时出错:调用init方法失败;嵌套异常为java.lang.noClas

  • 我在表中总共有8条记录,其中6条在spring批处理调用read时可以使用jpareader。现在我将页面大小和块大小设置为1以进行测试。期望作业运行时,它应该进行6次读取调用,然后它应该逐个处理,逐个写入。但实际上发生的是,它只是调用read 4次(从日志中我可以看到这样读取页面0...1)并处理4个,其中一个由于不匹配写入标准而被过滤掉,然后它只是更新了3个记录,作业标记为成功完成。