Multithreading 将ThreadPoolTaskExecutor与FlatFileItemReader和AsyncItemProcessor+一起使用是否线程安全;作家?

Multithreading 将ThreadPoolTaskExecutor与FlatFileItemReader和AsyncItemProcessor+一起使用是否线程安全;作家?,multithreading,csv,spring-batch,Multithreading,Csv,Spring Batch,我的作业读取csv文件(最多包含65000行),处理数据并写入数据库。下面是我的配置-- @Bean 公共作业csvFileLoadJob()引发异常{ 返回jobBuilderFactory.get(“csvFileLoadJob”) .防止重新启动() .start(csvFileLoadStep()) .build(); } @豆子 公共步骤csvFileLoadStep()引发异常{ 返回此.stepBuilderFactory.get(“csvFileLoadStep”) .trans

我的作业读取csv文件(最多包含65000行),处理数据并写入数据库。下面是我的配置--

@Bean
公共作业csvFileLoadJob()引发异常{
返回jobBuilderFactory.get(“csvFileLoadJob”)
.防止重新启动()
.start(csvFileLoadStep())
.build();
}
@豆子
公共步骤csvFileLoadStep()引发异常{
返回此.stepBuilderFactory.get(“csvFileLoadStep”)
.transactionManager(我的transactionManager)
.chunk(1000)
.reader(csvFileReader(null))
.processor(AsyncSvFileProcessor())
.writer(asyncTableWriter())
.容错()
.skipPolicy(fileskipphandler())
.节流限制(5)
.taskExecutor(csvFileLoadThreadPoolExecutor)
.build();
}
读取器将每一行读入一个映射(通过自定义
字段集映射器
)。编写器调用JpaRepository将转换后的实体(
MyPojo
)写入数据库

配置是线程安全的吗

在Spring元数据表中,我可以看到读取计数与文件的行计数相匹配。但是,目标表计数--正确插入到目标表中的记录+记录到单独表中的异常--远远超过行计数

是什么导致了这种差异?

我发现了这一点——如果其他人遇到同样的问题,请提交答案。 事实证明,
faultTolerant()
在重复的异常日志后面。如果发生故障,将回滚块并重试以隔离坏记录

我在
fileSkipHandler()
中记录自定义异常,因此回滚+重试将导致重复的异常日志。通过实现
@OnSkipInProcess
/
@OnSkipInWrite
方法来处理异常日志记录,我能够解决这个问题


Used thread for reference

是否有理由同时使用多线程步骤和异步处理器/写入程序?你试过一次只使用一种方法吗?@MahmoudBenHassine我正试图加快这个过程。尽管我的区块大小被设置为1000,但编写器总是一次获得一条记录。我能够解决重复问题(回答如下),但延迟问题仍然存在
    @Bean
    public Job csvFileLoadJob() throws Exception {
        return jobBuilderFactory.get("csvFileLoadJob")
                .preventRestart()
                .start(csvFileLoadStep())
                .build();
    }

    @Bean
    public Step csvFileLoadStep() throws Exception {
        return this.stepBuilderFactory.get("csvFileLoadStep")
                .transactionManager(myTransactionManager)
                .<Map<String, String>, MyPojo>chunk(1000)
                .reader(csvFileReader(null))
                .processor(asyncCsvFileProcessor())
                .writer(asyncTableWriter())
                .faultTolerant()
                .skipPolicy(fileSkipHandler())
                .throttleLimit(5)
                .taskExecutor(csvFileLoadThreadPoolExecutor)
                .build();
    }