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

Java 使用JPA事务处理Spring批处理错误,java,spring,spring-data-jpa,spring-batch,Java,Spring,Spring Data Jpa,Spring Batch,我有一个spring批处理工作,在happy path场景中以我想要的方式工作,但现在我专注于错误处理 我的目标是跳过一组已知错误,并在任何其他异常(如DB错误或外部API错误)上使作业失败。稍后我将重新启动作业。为了实现这一点,我创建了步骤配置为 .faultTolerant() .skip(SkippableException.class) .skip(FlatFileParseException.class) .skipLimit(Integer.MAX_VALUE

我有一个spring批处理工作,在happy path场景中以我想要的方式工作,但现在我专注于错误处理

我的目标是跳过一组已知错误,并在任何其他异常(如DB错误或外部API错误)上使作业失败。稍后我将重新启动作业。为了实现这一点,我创建了步骤配置为

.faultTolerant()
    .skip(SkippableException.class)
    .skip(FlatFileParseException.class)
    .skipLimit(Integer.MAX_VALUE)
    .retryLimit(0)
在一个集成测试中,我已经证明,如果在我的读卡器/处理器/写卡器中抛出可跳过的异常,那么作业将适当地跳过坏记录

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

这似乎是可行的,在我的写入程序执行后,在事务提交期间引发异常,我得到以下日志消息:

    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.
这似乎也是预期的行为。问题是,这并没有停止工作。该步骤退出到SimpleRetryExceptionHandler,它似乎认为异常不是致命的。它“重试”该块并将其标记为成功,然后作为成功完成继续

如果我在自己的逻辑中导致DB错误,从而强制在读卡器/处理器/写入程序中引发此异常,则作业将成功。。失败。

对于作为事务提交的一部分发生的异常,是否需要处理重试/跳过逻辑

更新:我可以确认跳过/重试设置是否正确,因为如果我在写入程序中插入EntityManager并调用flush(),作业将正确失败。但我绝对不想这么做


更新2:再次看,框架提供的JpaItemWriter实现似乎在write()方法的末尾调用entityManager.flush。。。所以我也可以这么做

在我自己的读卡器/处理器/编写器代码中没有抛出异常,这似乎是一个问题,因为在事务尝试提交之前,sql语句不会执行


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

您不需要
retryLimit(0)
我想证明一个不可预见的数据库错误会导致作业失败
:这种情况下,您需要告诉Spring Batch不要跳过这些异常,并使用以下命令使步骤(及其周围的作业)失败。你试过了吗?我添加了noSkip(Exception.class),它仍然有相同的行为。我认为问题在于,异常不是发生在我自己的编写器代码中,而是在提交jpa事务时发生在框架内部。事实上,即使我删除了faultTolerant()下除“noSkip(Exception.class)”之外的所有内容,作业仍然成功完成。这类似于吗?如果没有,请分享一个重现这个问题的例子,我会尽快看一看。谢谢。@MahmoudBenHassine很抱歉没有早点回复。它与该问题类似/相同,我通过在writer中刷新EntityManager修复了该问题,这与默认的JpaItemWriter类似。非常感谢。