1. JobRepository, JobExplorer, JobOperation 의 역할
- JobRepository : meta-data 에 대한 CRUD
- JobExplorer : meta-data 에 대한 read-only 기능
- JobOperation : stop, restart 등 job 에 대한 제어
2. jobOperator 의 stop(jobExecutionId) 메소드
- 실행중인 job 을 stop 시킨다.
- Stop 은 graceful 하게 동작한다. (Stop이 즉시 이뤄지지 않으며 현재 실행중이던 step 은 끝까지 다 실행 된 후 job이 stop 된다)
3. jobOperator 의 stop(jobExecutionId) 메소드 들여다 보기
(spring-batch-core-4.2.1 org.springframework.batch.core.launch.support.SimpleJobOperator.stop())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
@Override
@Transactional
public boolean stop(long executionId) throws NoSuchJobExecutionException, JobExecutionNotRunningException {
JobExecution jobExecution = findExecutionById(executionId);
// Indicate the execution should be stopped by setting it's status to
// 'STOPPING'. It is assumed that
// the step implementation will check this status at chunk boundaries.
BatchStatus status = jobExecution.getStatus();
if (!(status == BatchStatus.STARTED || status == BatchStatus.STARTING)) {
throw new JobExecutionNotRunningException("JobExecution must be running so that it can be stopped: "+jobExecution);
}
jobExecution.setStatus(BatchStatus.STOPPING);
jobRepository.update(jobExecution);
try {
Job job = jobRegistry.getJob(jobExecution.getJobInstance().getJobName());
if (job instanceof StepLocator) {//can only process as StepLocator is the only way to get the step object
//get the current stepExecution
for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
logger.info("STOP 메소드 내의 jobExecutionId : " + stepExecution.getJobExecutionId());
if (stepExecution.getStatus().isRunning()) {
try {
//have the step execution that's running -> need to 'stop' it
Step step = ((StepLocator)job).getStep(stepExecution.getStepName());
if (step instanceof TaskletStep) {
Tasklet tasklet = ((TaskletStep)step).getTasklet();
if (tasklet instanceof StoppableTasklet) {
StepSynchronizationManager.register(stepExecution);
logger.info("stop stoppableTasklet ! ");
((StoppableTasklet)tasklet).stop();
StepSynchronizationManager.release();
}
}
}
catch (NoSuchStepException e) {
logger.warn("Step not found",e);
}
}
}
}
}
catch (NoSuchJobException e) {
logger.warn("Cannot find Job object in the job registry. StoppableTasklet#stop() will not be called",e);
}
return true;
}
|
cs |
- StoppableTasklet 의 stop() 을 호출하고 있음을 알 수 있다.
- StoppableTasklet 은 Tasklet interface를 상속받는 interface이며 내부적으로 stop() 추상메소드를 갖고있다.
- batch job 에서 Tasklet 대신 StopTasklet 을 구현한 후 stop() 메소드를 오버라이딩 할 경우, jobOperator.stop() 호출시에 batch job 내의 flag 값 제어 등을 할 수 있다. 마치 리스너와 같이 동작한다.
4. stop 호출에 따른 meta-data 의 STATUS 필드 값 변화 순서
1. jobOperator.stop(jobExecutionId); 호출
2. step의 STATUS필드값이 stopped 로 바뀜 (step_execution 테이블의 status 필드값)
3. job 의 STATUS필드값이 stopping 으로 바뀜 (job_execution 테이블의 status 필드값)
4. 스텝이 끝난 후 job의 status를 stopped 로 바꿈
https://docs.spring.io/spring-batch/docs/current/reference/html/step.html
'back > Spring Framework' 카테고리의 다른 글
[Spring Batch+Quartz] 스프링 배치+쿼츠 설정 및 구현 Clustering 모드 사용 (3) | 2020.04.20 |
---|---|
@Transactional Propagation (전파속성), Isolation (격리수준레벨) 그리고 synchronized (0) | 2020.04.17 |
[Spring Fw] Bean 생명주기 : Init/Destroy 사용법 및 호출 순서 (0) | 2020.03.19 |
@Autowired @Resource @Inject Bean 탐색 기준 (0) | 2020.02.27 |
redirect, forward 차이 및 redirect 시 attribute 전달 방법 (0) | 2020.01.06 |