我想编写一个包含步骤的批处理作业(假设A、B、C、D)。该批处理应按以下方式执行:
A
|
B and C
|
D
但当前设置是:A -> B -> C -> D。 我想同时在不同的线程执行B和C。
B 和 C 的执行持续时间不同(假设 B 的持续时间为 5 分钟,C 的持续时间为 10 分钟)
步骤A:截断数据库中的某些表。
步骤 B 和 C:批量读取和写入 2000 块。
读取器:JdbcCursorItemReader | 处理器:未使用| 作者:JdbcBatchItemWriter
步骤 D:运行 PL/SQL 过程,该过程取决于步骤 B 和 C 中的数据写入,因此只有在 B 和 C 成功完成后才应开始。
我正在使用 Quartz 调度程序来运行这项作业。因此,请告诉我是否需要使用多线程来运行此作业,因为目前它仅在一个工作线程中运行。
请也写下代码。
当前工作设置:
public Job demoJob(){
return jobBuilderFactory.get("demoJob")
.listener(jobExecutionListener())
.start(A())
.next(B())
.next(C())
.next(D())
.build();
}
期望:
public Job demoJob(){
return jobBuilderFactory.get("demoJob")
.listener(jobExecutionListener())
.start(A())
.next(B() and C()) // How to setup this
.next(D())
.build();
}
只要可以将需要并行化的应用程序逻辑拆分为不同的职责并分配给各个步骤,就可以在单个进程中并行化。并行步骤执行易于配置和使用。
使用Java配置时,与step3并行执行步骤(step1,step2)很简单,如下所示:
@Bean
public Job job(JobRepository jobRepository) {
return new JobBuilder("job", jobRepository)
.start(splitFlow())
.next(step4())
.build() //builds FlowJobBuilder instance
.build(); //builds Job instance
}
@Bean
public Flow splitFlow() {
return new FlowBuilder<SimpleFlow>("splitFlow")
.split(taskExecutor())
.add(flow1(), flow2())
.build();
}
@Bean
public Flow flow1() {
return new FlowBuilder<SimpleFlow>("flow1")
.start(step1())
.next(step2())
.build();
}
@Bean
public Flow flow2() {
return new FlowBuilder<SimpleFlow>("flow2")
.start(step3())
.build();
}
@Bean
public TaskExecutor taskExecutor() {
return new SimpleAsyncTaskExecutor("spring_batch");
}
可配置任务执行器用于指定哪个 TaskExecutor 实现应执行各个流程。默认为 SyncTaskExecutor,但需要异步 TaskExecutor 才能并行运行步骤。请注意,该作业确保拆分中的每个流程在聚合退出状态和转换之前完成。