如何使用不同的参数同时启动相同的 spring-批处理作业?
How to start the same spring-batch job concurrently with different parameters?
我想使用不同的 filename
参数多次启动相同的作业配置,以同时导入多个文件(每个作业一个文件)。
@Configuration
public class MyJob {
//the steps contain each a reader, processor and writer
//reader is @JobScope
@Bean
public Job job(Step someStep, Step, someMoreStep) {
System.out.println("registering job bean");
return jobBuilderFactory.get(name)
.start(someStep)
.next(someMoreStep)
.build();
}
}
@Component
public class MyImporter {
@Autowired
private JobRegistry jobRegistry;
@Autowired
private JobLauncher launcher;
private static final String FILENAME = "baseFilename";
@Async
public void run(String i) {
p = new JobParametersBuilder();
p.addDate("date", new Date());
p.addString("filename", FILENAME + i + ".csv"); //injected via @Value jobParameter to job
Job job = jobRegistry.getJob("getMyJob");
launcher.run(job, p.toJobParameters());
}
}
@Component
public class MyImportManager {
@Autowired
private MyImporter importer;
//starts a job multiple times with different "filename" parameters,
//to simulate concurrent file imports with the same configuration job class
public void start() {
for (int i = 0; i < 4; i++) {
importer.run(i);
}
}
}
@SpringBootApplication
@EnableBatchProcessing(modular = true)
@EnableAsync
public class MyConfig {
}
问题:我可以开始多项工作,但它们似乎使用相同的 reader
。如果我 运行 一份工作 i < 1
,一切正常。如果我增加 i
,我会得到奇怪的输入。
我正在使用 FlatFileItemReader,其中每个值都是逐行读取的。但是当使用并发导入(来自不同的文件)时,输入的字符串通常是损坏的。
所以我假设我没有为并发导入正确注册作业?但是为什么?
有趣的是:"registering job bean"
行只打印了一次。但是它不应该随着异步作业的启动而频繁打印吗?
FlatFileItemReader
不是线程安全的,因此您的 reader bean 需要在 "job" 范围内。然后您将获得每个作业一个实例。
@Bean
@JobScope
public FlatFileItemReader<?> yourReaderBean(
@Value("#{jobParameters[filename]}") String filename){
FlatFileItemReader<?> itemReader = new FlatFileItemReader<?>();
itemReader.setLineMapper(lineMapper());
itemReader.setResource(new ClassPathResource(filename));
return itemReader;
}
我想使用不同的 filename
参数多次启动相同的作业配置,以同时导入多个文件(每个作业一个文件)。
@Configuration
public class MyJob {
//the steps contain each a reader, processor and writer
//reader is @JobScope
@Bean
public Job job(Step someStep, Step, someMoreStep) {
System.out.println("registering job bean");
return jobBuilderFactory.get(name)
.start(someStep)
.next(someMoreStep)
.build();
}
}
@Component
public class MyImporter {
@Autowired
private JobRegistry jobRegistry;
@Autowired
private JobLauncher launcher;
private static final String FILENAME = "baseFilename";
@Async
public void run(String i) {
p = new JobParametersBuilder();
p.addDate("date", new Date());
p.addString("filename", FILENAME + i + ".csv"); //injected via @Value jobParameter to job
Job job = jobRegistry.getJob("getMyJob");
launcher.run(job, p.toJobParameters());
}
}
@Component
public class MyImportManager {
@Autowired
private MyImporter importer;
//starts a job multiple times with different "filename" parameters,
//to simulate concurrent file imports with the same configuration job class
public void start() {
for (int i = 0; i < 4; i++) {
importer.run(i);
}
}
}
@SpringBootApplication
@EnableBatchProcessing(modular = true)
@EnableAsync
public class MyConfig {
}
问题:我可以开始多项工作,但它们似乎使用相同的 reader
。如果我 运行 一份工作 i < 1
,一切正常。如果我增加 i
,我会得到奇怪的输入。
我正在使用 FlatFileItemReader,其中每个值都是逐行读取的。但是当使用并发导入(来自不同的文件)时,输入的字符串通常是损坏的。
所以我假设我没有为并发导入正确注册作业?但是为什么?
有趣的是:"registering job bean"
行只打印了一次。但是它不应该随着异步作业的启动而频繁打印吗?
FlatFileItemReader
不是线程安全的,因此您的 reader bean 需要在 "job" 范围内。然后您将获得每个作业一个实例。
@Bean
@JobScope
public FlatFileItemReader<?> yourReaderBean(
@Value("#{jobParameters[filename]}") String filename){
FlatFileItemReader<?> itemReader = new FlatFileItemReader<?>();
itemReader.setLineMapper(lineMapper());
itemReader.setResource(new ClassPathResource(filename));
return itemReader;
}