在春季批次的ItemWriter中无法捕获异常

2022-02-28 00:00:00 spring java spring-batch

我正在编写一个Spring批处理过程来将数据集从一个系统迁移到另一个系统。在本例中,这与使用RowMapper实现在将对象移交给ItemWriter之前从查询构建对象一样简单。ItemWriter调用我的DAO上的save方法(定义为接口,由Spring数据处理)

问题是:我对MyItem表有一个唯一的约束,因此保存重复的记录将导致DataIntegrityViolationException。我曾尝试在ItemWriter中捕获它,以允许我记录没有导入记录,但是在执行过程中,它从未进入该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: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

相关文章