无法在spring批处理的ItemWriter中捕获异常

时间:2015-03-19 13:42:54

标签: java spring spring-batch

我正在编写一个Spring Batch流程来将数据集从一个系统迁移到另一个系统。在这种情况下,这就像使用RowMapper实现在切换到ItemWriter之前从查询构建对象一样简单。 ItemWriter在我的DAO上调用save方法(定义为接口并由spring数据处理)

问题是:我对MyItem表有一个唯一约束,因此保存重复记录将导致DataIntegrityViolationException。我已经尝试在ItemWriter内捕获它以允许我记录未导入记录,但是在执行期间它永远不会进入此catch语句。我试图抓住ExceptionThrowable也无济于事。

从我注意到的内容中,有一个@Transactional注释'保存'我的DAO的方法,我希望提交和刷新发生。 Spring Batch是否以任何方式改变了这个交易?这样@Transactional注释适用于“写入”#39; ItemWriter

的方法

我可以在这堂课中捕捉到异常吗?

我已在下方提供了代码段,如果您需要更多信息,请与我们联系。

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

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 个答案:

答案 0 :(得分:2)

这里有几点:

  1. 删除DAO上的@Transactional注释。 @Transactional和Spring Batch通常不会很好。 Spring Batch将事务作为框架功能的一部分进行管理,并且尝试操作该功能可能会导致意外的副作用。
  2. 正如M. Deinum指出的那样,您的ItemWriter因此您的DAO正在参与Spring Batch正在管理的事务。因此,在事务提交之前,您不会得到该异常。
  3. 考虑到上述考虑因素,您有两种选择:

    1. 您可以配置跳过逻辑以跳过抛出该异常的记录。如果需要记录该项目,可以在混合中添加SkipListener,以便记录导致异常的项目。但是,使用此方法需要支付性能损失,因为抛出异常将导致事务被回滚并一次重放一个项目。
    2. 您可以通过ItemProcessor过滤相关项目。这样可以节省跳过逻辑的性能损失。
    3. 您可以在5.1.5节中阅读有关Spring Batch跳过逻辑的更多信息:http://docs.spring.io/spring-batch/trunk/reference/html/configureStep.html