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

spring批处理、JpaRepository和回滚

孟昊空
2023-03-14

我有一个spring批处理应用程序(spring boot 2.3.5版),它在spring批处理时使用一个JpaRepository将一些自定义日志消息插入数据库。这与开箱即用的spring批处理表是分开的。似乎当我从ItemProcessorAdapter抛出异常时,它会被ItemProcessListener onProcessError()方法捕获。在这个方法中,我执行一个JpaRepository save()和flush()。不会记录任何错误,但是一旦我离开这个方法,JpaRepository就会回滚。

  1. 这是正常行为吗?我怎样才能避开它?
  2. 在使用JpaRepository时,是否有方法设置@transactional(noRollbackFor={xxxException.class})?我试了一下,似乎没有效果。

下面是示例代码段。

java prettyprint-override">
@Configuration
public class BatchJobConfiguration {

   //Omitted for clarity....

    @Bean
    @StepScope
    public CompositeItemProcessor<Decision,Decision> itemProcessor() {
        CompositeItemProcessor<Decision,Decision> itemProcessor = new CompositeItemProcessor<>();
        itemProcessor.setDelegates(Arrays.asList(
                decisionValidatingItemProcessor(),
                myItemProcessor(null)
        ));
        return itemProcessor;
    } // end itemProcessor()
    
     @Bean
    public BeanValidatingItemProcessor<Decision> decisionValidatingItemProcessor() {
        BeanValidatingItemProcessor<Decision> beanValidatingItemProcessor = new BeanValidatingItemProcessor<>();
        beanValidatingItemProcessor.setFilter(true);
        return beanValidatingItemProcessor;
    } // end decisionValidatingItemProcessor()

    @Bean
    public ItemProcessorAdapter<Decision,Decision> myItemProcessor(DecisionProcessingService service) {
        ItemProcessorAdapter<Decision,Decision> adapter = new ItemProcessorAdapter<>();
        adapter.setTargetObject(service);
        adapter.setTargetMethod("processDecision");
        return adapter;
    }
    
    @Bean
    @StepScope
    public DecisionItemProcessListener decisionItemProcessListener() {
        return new DecisionItemProcessListener(mpJpaRepository);
    }


}

@Service
public class DecisionProcessingService {

    public Decision processDecision(Decision decision) throws BatchException {
        ....
        throw new BatchException("An error occurred");
    
    }

}



public class DecisionItemProcessListener implements ItemProcessListener<Decision,Decision> {
    private MyJpaRepository mpJpaRepository;

    public DecisionItemProcessListener(MyJpaRepository mpJpaRepository) {
        this.mpJpaRepository = mpJpaRepository;
    }
    
    ....
    
    @Override
    public void onProcessError(Decision decision, Exception e) {
        MyEntityObject obj = MyEntityObject.builder()
                .msg(e.getMessage())
                .build();
        mpJpaRepository.save(obj);
        mpJpaRepository.flush();
        
        // after this, the insert above is rolled back.
    } // end onProcessError()
}

共有1个答案

曾承弼
2023-03-14

您在这里使用的回调ItemProcessListener#OnProcessError是在一个事务(由spring批处理驱动)中调用的,该事务将由于项处理器引发的异常而回滚。

如果要在该方法中保存数据,则需要使用新事务(使用requires_new传播)。

编辑:我在这里分享了一个最小的完整示例:https://github.com/benas/spring-batch-lab/tree/master/issues/so64913980。

 类似资料:
  • 问题内容: 我的问题与春季批次和交易有关。 假设我为我的步骤之一选择了 50 的 提交间隔 。 还要假设我总共有1000条记录,其中一条记录将导致itemWriter失败,从而导致整个块的回滚(在我的示例中为50条记录)。 确保作业完成(并忽略有问题的块)后将49个有效记录写入数据库的状态有哪些? 问题答案: 经过研究,我得出以下结论: 如果项目编写者未能提交一个块(此处为50个项目)从而导致回滚

  • 在我的项目中配置了以下内容: 加载文件时,我有重复的记录,但因为我配置了在下,Spring batch不应回滚记录,但仍将回滚记录。如果我从列表中删除,那么它将抛出异常。我们正在使用Spring批处理版本: 不希望回滚记录,但会回滚记录。

  • 我有一个compositeItemWriter,它有2个代理编写器:1。HeaderWriter将一些字段从我的对象写入头表2。DetailWriter将文件写入详细表。 context.xml:

  • 我有一个Spring批处理作业,它通过SFTP从远程Linux服务器检索文件。远程服务器上的目录是一个包含七天文件(约400个文件)的存档。文件的大小相对较小。 Spring批处理知道哪些文件已经被处理。 当我启动应用程序时。第一次,Spring Batch tasklet检索文件时,Spring Batch会为它已经处理的每个文件生成一个异常: > 在Transformer类中,是否应该检查文件

  • 我有以下工作要处理在一定的时间间隔或特别的基础上。 作业中的步骤如下: 我也想要用户界面,在那里我可以触发一个特别的基础上的工作,而且我应该能够提供参数从用户界面。 我想用Spring batch来完成这个任务,但它更多的是用于读->处理->写之类的工作。这里,在第一步中,我正在生成由第二步读取的数据。我不确定我是否还可以使用Spring batch来实现这个,或者有更好的方法来实现这个。