강의메모 #
스프링 배치 도메인 이해 - StepContribution #
기본 개념 #
- 청크 프로세스의 변경 사항을 버퍼링 한 후 StepExecution 상태를 업데이트하는 도메인 객체
- 청크 커밋 직전에 StepExecution 의 apply 메서드를 호출하여 상태를 업데이트 함
- ExitStatus 의 기본 종료코드 외 사용자 정의 종료코드를 생성해서 적용 할 수 있음
구조 #
참고 #
https://devfunny.tistory.com/687
- apply() 메서드를 호출한 경우 : StepContribution의 변경 사항이 StepExecution에 반영
- apply() 메서드를 호출하지 않을 경우 : StepExecution에 StepContribution의 변경 사항이 반영안됨
Spring Batch에서는 일반적으로 StepContribution의 변경 사항이 자동으로 StepExecution에 적용된다. 따라서 apply()를 수동으로 호출해 줄 필요는 없다. 일반적으로 Spring Batch의 구현은 내부적으로 Step의 실행 도중 StepContribution 객체를 업데이트하고, Step이 완료될 때 해당 변경 사항을 StepExecution에 자동으로 반영한다.
TaskletStep.java
public RepeatStatus doInTransaction(TransactionStatus status) {
TransactionSynchronizationManager.registerSynchronization(this);
RepeatStatus result = RepeatStatus.CONTINUABLE;
StepContribution contribution = this.stepExecution.createStepContribution();
TaskletStep.this.chunkListener.beforeChunk(this.chunkContext);
this.oldVersion = new StepExecution(this.stepExecution.getStepName(), this.stepExecution.getJobExecution());
this.copy(this.stepExecution, this.oldVersion);
try {
try {
result = TaskletStep.this.tasklet.execute(contribution, this.chunkContext);
if (result == null) {
result = RepeatStatus.FINISHED;
}
} catch (Exception var17) {
if (TaskletStep.this.transactionAttribute.rollbackOn(var17)) {
this.chunkContext.setAttribute("sb_rollback_exception", var17);
throw var17;
}
} finally {
try {
this.semaphore.acquire();
this.locked = true;
} catch (InterruptedException var15) {
TaskletStep.logger.error("Thread interrupted while locking for repository update");
this.stepExecution.setStatus(BatchStatus.STOPPED);
this.stepExecution.setTerminateOnly();
Thread.currentThread().interrupt();
}
if (TaskletStep.logger.isDebugEnabled()) {
TaskletStep.logger.debug("Applying contribution: " + contribution);
}
this.stepExecution.apply(contribution);
}
...
}