Springboot 批处理 - 使用 JdbcPagingItemReader,当没有数据 select 时,作业就会挂起

Springboot batch - Using JdbcPagingItemReader and the job is getting is getting hung up when there is no data to select

我遇到了一个问题,看起来像是使用 JdbcPagingItemReader 的方法被挂断了。

当 reader 到 return 中有信息时一切正常,但是当 select 没有信息到 return 时下面的 select 运行时,事情就不会了不太好用(即工作挂起)。

此外,当删除 taskExecutor(和 throttleLimit)步骤时,reader 步骤运行到完成,即使 select 没有信息,一切看起来也很好。考虑到这一点,我不确定多线程在其中扮演什么角色(如果有的话)或者我的 reader 方法是否有缺陷。

在下面的例子中,你会看到 select 非常简单,因为它从一个 table 读取,连接到另一个,然后 selects 具有特定状态和给定日期范围内的行。

如果有帮助,请提供其他信息...

Springboot版本2.5.6,数据库使用java17,MySql

感谢您提供的任何建议或见解,因为我现在很困惑。

谢谢。


@Configuration
@EnableBatchProcessing
public class BuildOpenStatusConfigurationJob {

    @Autowired
    JobBuilderFactory jobBuilderFactory;

    @Autowired
    StepBuilderFactory stepBuilderFactory;

    @Autowired
    DataSource dataSource;
....

    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(12);
        executor.setMaxPoolSize(16);
        executor.setQueueCapacity(12);
        executor.initialize();
        return executor;
    }

    @Bean
    public Step createStsActivity() {
        return this.stepBuilderFactory.get("createStsActivity")
                .<StsActivity, StsActivity>chunk(1000)
                .reader(stsActivityItemReader(null, null))
                .processor(stsActivityItemProcessor())
                .writer(stsActivityItemWriter())
                .taskExecutor(taskExecutorRows())
                .throttleLimit(16)
                .listener(statusStepExecutionListener())
                .build();
    }

    @Bean
    @StepScope
    public JdbcPagingItemReader<StsActivity> stsActivityItemReader(
            @Value("#{jobParameters['lowerDateThreshold']}") String lowerDateThreshold,
            @Value("#{jobParameters['upperDateThreshold']}") String upperDateThreshold) {

        JdbcPagingItemReader<StsActivity> pagingItemReader = new JdbcPagingItemReader<>();

        pagingItemReader.setDataSource(dataSource);
        pagingItemReader.setFetchSize(10000);
        pagingItemReader.setPageSize(10000);
        pagingItemReader.setRowMapper(new BeanPropertyRowMapper<>(StsActivity.class));

        MySqlPagingQueryProvider mySqlPagingQueryProvider = new MySqlPagingQueryProvider();

        mySqlPagingQueryProvider.setSelectClause(ta.statusId as statusId, tb.eventDate as maxEventDate, tb.id as maxEventId ");
        mySqlPagingQueryProvider.setFromClause("FROM TableA ta" 
                 + "join TableB tb on tb.statusId = ta.statusId");
        mySqlPagingQueryProvider.setWhereClause("WHERE tb.status = 'OPEN' "
                + "and (date(tb.eventDate) >= date('" + lowerDateThreshold + "') "
                + "and date(tb.eventDate) < date('" + upperDateThreshold + "'))");

        Map<String, Order> orderByKeys = new HashMap<>();
        orderByKeys.put("rbpai.statusId", Order.ASCENDING);
        mySqlPagingQueryProvider.setSortKeys(orderByKeys);

        pagingItemReader.setQueryProvider(mySqlPagingQueryProvider);
        
        return pagingItemReader;
    }

这已在 v4.3.4 中修复:https://github.com/spring-projects/spring-batch/issues/3898

使用 Spring Boot 2.5.6,您将获得 Spring Batch v4.3.3,其中不包含修复程序。

如果您升级到包含 Batch 4.3.4+ 的启动版本,您的问题应该会得到解决。否则,它可能是一个回归。在这种情况下,请在 Github 上添加一条评论,其中包含重现该问题的 minimal complete example,我们将 re-open 进行调查。先谢谢你。