java - 无法捕获 Spring Batch 的 ItemWriter 中的异常

标签 java spring spring-batch

我正在编写一个 Spring Batch 流程来将数据集从一个系统迁移到另一个系统。在本例中,这就像使用 RowMapper 实现从查询构建对象,然后再传递给 ItemWriter 一样简单。 ItemWriter 调用我的 DAO 上的 save 方法(定义为接口(interface)并由 spring 数据处理)

问题是这样的:我对 MyItem 表有唯一的约束,因此保存重复的记录将导致 DataIntegrityViolationException。我尝试在 ItemWriter 中捕获此内容,以允许我记录未导入的记录,但是在执行过程中它永远不会输入此 catch 语句。我 try catch ExceptionThrowable 也无济于事。

据我所知,我的 DAO 的“save”方法上有一个 @Transactional 注释,我希望在其中发生提交和刷新。 Spring Batch 是否会以任何方式改变此事务?这样 @Transactional 注释适用于 ItemWriter 的“write”方法?

我能捕获这个类中的异常吗?

我在下面提供了代码片段,如果您需要更多信息 - 请告诉我。

非常感谢您提供的任何帮助

ItemWriter

@Component
public class MyItemWriter implements ItemWriter<MyItem> {

    private static final Logger LOG = LoggerFactory.getLogger(MyItemWriter.class);

    @Resource
    private MyItemDao myItemDao;

    @Override
    public void write(List<? extends MyItem> myItems) throws Exception {
        for (MyItem myItem : myItems) {
            try {
                myItemDao.save(myItem);
            } catch (Throwable ex) {
                LOG.warn("Failed to import MyItem: {}: {} ", myItem.getId(), ex.toString());
            }
        }
    }
}

DAO

public interface MyItemDao extends PagingAndSortingRepository<MyItem, Integer> {
    [Custom methods omitted]
}

Spring Batch 配置

<batch:job id="myImportJob" restartable="true" job-repository="jobRepository">
    <batch:step id="myImportStep" allow-start-if-complete="true">
        <batch:tasklet>
            <batch:chunk reader="myItemReader" writer="myItemWriter" commit-interval="50" />
        </batch:tasklet>
    </batch:step>
</batch:job>

最佳答案

这里有几点:

  1. 删除 DAO 上的 @Transactional 注释。 @Transactional 和 Spring Batch 通常效果不佳。 Spring Batch 将事务作为框架功能的一部分进行管理,尝试操纵该功能可能会导致意外的副作用。
  2. 正如 M. Deinum 指出的那样,您的 ItemWriter 以及您的 DAO 正在参与 Spring Batch 正在管理的事务。因此,在事务提交之前您不会收到该异常。

考虑到上述因素,您有两个选择:

  1. 您可以配置跳过逻辑来跳过引发该异常的记录。如果您需要记录该项目,可以将 SkipListener 添加到组合中,以便可以记录导致异常的项目。但是,这种方法会带来性能损失,因为抛出异常将导致事务回滚并一次重播一项。
  2. 您可以通过 ItemProcessor 过滤项目。这可以节省跳过逻辑的性能损失。

您可以在第 5.1.5 节中阅读有关 Spring Batch 跳过逻辑的更多信息:http://docs.spring.io/spring-batch/trunk/reference/html/configureStep.html

关于java - 无法捕获 Spring Batch 的 ItemWriter 中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29146209/

相关文章:

spring-batch - @BeforeStep 注释的方法没有被调用

java - 在 Java 中执行 SQL 批量更新,如果传入的 parm 为 null,则不会更新字段

java - 无法自动连接[错误 : No matching bean of type]

java - 无法部署 apache tomcat web 应用程序 - 总是 404

Spring+JSP url构建最佳实践

javascript - 在 SPRING MVC 中使用 JSON 发出 POST 请求的正确方法?

java - 使用 JPA 存储库保留 Spring Batch ItemWriter 的问题

集群环境中的 Java Batch 作业

java - 如何在Java Swing中的TextArea上设置滚动条?

Java比较器按多个字段排序,字段计数应该是动态的