【发布时间】:2021-06-25 08:08:36
【问题描述】:
问题
我有点困惑,因为当通过 HTTP 请求开始执行 Spring Batch 作业时,如果我收到另一个 HTTP 请求来启动相同的作业,但在作业执行时使用不同的参数,正在执行的作业已执行停止未完成并开始处理新作业。
上下文
我开发了一个 API REST 来加载和处理 Excel 文件的内容。 Web 服务公开了两个端点,一个用于加载、验证和存储数据库中 Excel 文件的内容,另一个用于开始处理存储在数据库中的记录。
它是如何工作的
-
POST /api/excel/上传 此端点接收 Excel 文件。当收到请求时,每个文件都被分配一个唯一的标识符并验证其内容。如果内容正确,则将其插入到等待处理的临时表中。
-
GET /api/Excel/process?id=x 该端点接收要处理的文件的标识符。当收到请求时,会启动一个 Spring Batch 作业来处理临时表中的记录。
一些代码
- 控制器
@PostMapping(produces = {APPLICATION_JSON_VALUE})
public ResponseEntity<Page<ExcelLoad>> post(@RequestParam("file") MultipartFile multipartFile)
{
return super.getResponse().returnPage(service.upload(multipartFile));
}
@GetMapping(value = "/process", produces = APPLICATION_JSON_VALUE)
public DeferredResult<ResponseEntity<Void>> get(@RequestParam("id") Integer idCarga)
{
DeferredResult<ResponseEntity<Void>> response = new DeferredResult<>(1000L);
response.onTimeout(() -> response.setResult(super.getResponse().returnVoid()));
ForkJoinPool.commonPool().submit(() -> service.startJob(idCarga));
return response;
}
我使用 DeferredResult 在收到请求后向客户端发送响应,而不等待作业完成
- 服务
public void startJob(int idCarga)
{
JobParameters params = new JobParametersBuilder()
.addString("mainJob", String.valueOf(System.currentTimeMillis()))
.addString("idCarga", String.valueOf(idCarga))
.toJobParameters();
try
{
jobLauncher.run(job, params);
}
catch (JobExecutionException e)
{
log.error("---ERROR: {}", e.getMessage());
}
}
- 批次
@Bean
public Step mainStep(ReaderImpl reader, ProcessorImpl processor, WriterImpl writer)
{
return stepBuilderFactory.get("step")
.<List<ExcelLoad>, Invoice>chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.faultTolerant().skipPolicy(new ExceptionSkipPolicy())
.listener(stepSkipListener)
.build();
}
@Bean
public Job mainJob(Step mainStep)
{
return jobBuilderFactory.get("mainJob")
.listener(mainJobExecutionListener)
.incrementer(new RunIdIncrementer())
.start(mainStep)
.build();
}
执行一些测试,我观察到以下行为:
【问题讨论】:
标签: java excel spring-boot spring-batch