在itemwriter中,春季批处理未在运行时异常上滚动

Posted

技术标签:

【中文标题】在itemwriter中,春季批处理未在运行时异常上滚动【英文标题】:spring batch not rolling on runtime exception in itemwriter 【发布时间】:2019-04-05 08:31:15 【问题描述】:

我是 Spring Batch 的新手,我有一个带有 Oracle 数据库的 Spring Data 项目的 Spring Batch。基本上为简单起见,我有两个步骤:

第1步:读取csv文件的第一行而不是在itemwriter的table_header中插入

第 2 步:从 csv 文件的第二行读取,而不是在 itemwriter 的 table_detail 中插入。

table_header 链接到 table_detail - 一对多关系。

基本上,如果在保存详细信息后在第 2 步中触发了运行时异常,而在同一步骤中数据不会回滚。根据弹簧参考,它应该在运行时异常上回滚。

我不确定为了让交易回滚我缺少什么,有人可以指出正确的方向吗?

请在下面找到我的数据库配置:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "dummyEntityManager", transactionManagerRef = "dummyTransactionManager", basePackages = 
        "com.dummy.persistence" )
@PropertySource("file:$test_PROPERTIES")
public class DatabaseConfig extends HikariConfig 


    @Bean(name = "dummyDatasource")
    public HikariDataSource dataSource() 
        HikariDataSource hikariDataSource = new HikariDataSource();
        hikariDataSource.setJdbcUrl(CipherWrapper.getInstance().decrypt(jdbcUrl));
        hikariDataSource.setUsername(CipherWrapper.getInstance().decrypt(username));
        hikariDataSource.setPassword(CipherWrapper.getInstance().decrypt(password));
        hikariDataSource.setAutoCommit(false);
        hikariDataSource.setMaximumPoolSize(maximumPoolSize);
        hikariDataSource.setMinimumIdle(minimumIdle);
        return hikariDataSource;
    


    @Bean(name = "dummyEntityManager")
    public LocalContainerEntityManagerFactoryBean dummyEntityManagerFactory(EntityManagerFactoryBuilder builder) 
        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = builder.dataSource(dataSource())
                .packages("com.dummy.persistence.entity").persistenceUnit("dummyPersistenceUnit").build();

        localContainerEntityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());


        return localContainerEntityManagerFactoryBean;
    


    @Bean(name = "dummyTransactionManager")
    public PlatformTransactionManager dummyTransactionManager(
            @Qualifier("dummyEntityManager") EntityManagerFactory dummyEntityManagerFactory) 
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(dummyEntityManagerFactory);
        jpaTransactionManager.setRollbackOnCommitFailure(true);
        return jpaTransactionManager;
    


@Bean
public BatchConfigurer batchConfigurer(@Qualifier("dummyEntityManager") EntityManagerFactory dummyEntityManagerFactory) 
        return new DefaultBatchConfigurer() 
                @Override
                public PlatformTransactionManager getTransactionManager() 
                        return  dummyTransactionManager(dummyTransactionManager);
                
        ;


请在下面找到两个步骤配置:

@Bean("step1")
public Step headerSaveStep() 

StepBuilder stepBuilder = stepBuilderFactory.get(Flow.STEP1.toString());
SimpleStepBuilder<HeaderDetailsDto,HeaderDetailsAdditionaDto> simpleStepBuilder = stepBuilder
        .<HeaderDetailsDto, HeaderDetailsAdditionaDto>chunk(1);
simpleStepBuilder.reader(csvItemReader.csvFileVatPayerDetailsItemReader(null));
simpleStepBuilder.processor(EnrichmentProcessor());
simpleStepBuilder.writer(headerWriter());
simpleStepBuilder.allowStartIfComplete(true);
return simpleStepBuilder.build();

@Bean("step2")
public Step detailSaveStep() 

StepBuilder stepBuilder = stepBuilderFactory.get(Flow.STEP2.toString());
SimpleStepBuilder<DetailsDto, DetailsDto> simpleStepBuilder = stepBuilder
        .<DetailsDto, DetailsDto>chunk(20000);
simpleStepBuilder.reader(csvItemReader.csvFileBuyerDetailsFileItemReader(null));
simpleStepBuilder.writer(detailsWriter());
simpleStepBuilder.allowStartIfComplete(true);
return simpleStepBuilder.build();

【问题讨论】:

【参考方案1】:

Spring Batch 没有使用您的事务管理器。您需要定义一个引用它的BatchConfigurer bean(参见示例here)。希望这会有所帮助。

【讨论】:

谢谢,我已经添加了 bean batchConfigurer 请参见上面的 DatabaseConfig 但它仍然是相同的行为。我想我在这里缺少一些额外的配置? 您使用哪个版本的 Spring Batch? 您好,很抱歉回复延迟,我使用的是 Spring Batch Core 4.0.1.RELEASE 好的,谢谢,我在回答中展示的方法适用于 4.1.0.RELEASE 版本。作为记录,这已在jira.spring.io/browse/BATCH-2294 中修复。

以上是关于在itemwriter中,春季批处理未在运行时异常上滚动的主要内容,如果未能解决你的问题,请参考以下文章

事务未在春季批处理项目编写器中回滚

春季批处理继续运行

Spring批处理ItemWriter异常正在杀死工作

在春季批处理(spring-boot-1.5.2.RELEASE)中使用多个数据源在启动时引发异常

ItemWriter 的 Spring Batch 跳过异常

OAuth2用户详细信息未在春季安全(SpringBoot)中更新