Java Spring批处理ThreadPoolTaskExecutor钩子和JVM销毁进程don';完不成

Java Spring批处理ThreadPoolTaskExecutor钩子和JVM销毁进程don';完不成,java,spring,spring-batch,Java,Spring,Spring Batch,我的Spring批处理示例从文件读取并写入内存db中的h2 当流没有抛出异常时,一切都很顺利 如果引发SQL异常,任务执行器的两个线程将保持运行模式,而DestroJavaVM未完成,将保持运行模式 我的工作: @Bean public Job importUserJob(JobCompletionNotificationListener listener, Step step1) { return jobBuilderFactory.get("importUserJob").i

我的Spring批处理示例从文件读取并写入内存db中的h2

当流没有抛出异常时,一切都很顺利

如果引发SQL异常,任务执行器的两个线程将保持运行模式,而DestroJavaVM未完成,将保持运行模式

我的工作:

    @Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
    return jobBuilderFactory.get("importUserJob").incrementer(new RunIdIncrementer())
            .listener(listener)
            .flow(masterStep()).end().build();
}

@Bean
@Qualifier("masterStep")
public Step masterStep() {
    return stepBuilderFactory
            .get("masterStep")
            .partitioner("step1", partitioner)
            .step(step1())
            .taskExecutor(taskExecutor)
            .build();
}

@Bean
public Step step1() {
    return stepBuilderFactory.get("step1").<Person, Person>chunk(10)
            .reader(personItemReader)
            .processor(new PersonItemProcessor())
            .writer(writer)
            .listener(writerListener)
            .faultTolerant()
            .skip(DuplicateKeyException.class)
            .skipLimit(10)
            .build();
}
@Bean
公共作业导入器作业(作业完成通知侦听器侦听器,步骤1){
返回jobBuilderFactory.get(“importUserJob”).incrementer(新的RunIdIncrementer())
.listener(侦听器)
.flow(masterStep()).end().build();
}
@豆子
@限定词(“主步骤”)
公共步骤masterStep(){
返回stepBuilderFactory
.get(“masterStep”)
.分割器(“步骤1”,分割器)
.步骤(步骤1())
.taskExecutor(taskExecutor)
.build();
}
@豆子
公共步骤第1步(){
返回stepBuilderFactory.get(“step1”).chunk(10)
.读卡器(personItemReader)
.processor(新PersonItemProcessor())
.作者(作者)
.listener(writerListener)
.容错()
.skip(DuplicateKeyException.class)
斯基普利米特先生(10)
.build();
}
有什么问题吗


作业完成后,您是否尝试关闭任务执行器?请参阅使用任务执行器关机终止批处理。我不明白为什么这是必要的。如果没有关闭,如果没有引发异常,批处理将正确终止。