Split the function
This commit is contained in:
Binary file not shown.
@@ -18,35 +18,44 @@ import org.springframework.batch.core.step.tasklet.Tasklet;
|
||||
import org.springframework.batch.repeat.RepeatStatus;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
/**
|
||||
* Child Job 실행 Tasklet (Parent Job용)
|
||||
*
|
||||
* <p>진행 중인 모든 분석 회차(AnalCntInfo)를 조회하여 각 회차마다 독립적인 Child Job을 실행합니다. 각 Child Job은 3개의
|
||||
* <p>
|
||||
* 진행 중인 모든 분석 회차(AnalCntInfo)를 조회하여 각 회차마다 독립적인 Child Job을 실행합니다. 각 Child Job은
|
||||
* 3개의
|
||||
* Step(makeGeoJson → dockerRun → zipResponse)을 순차적으로 실행합니다.
|
||||
*
|
||||
* <p><b>주요 기능:</b>
|
||||
* <p>
|
||||
* <b>주요 기능:</b>
|
||||
*
|
||||
* <ul>
|
||||
* <li>진행 중인 분석 회차 목록 조회 (tb_map_sheet_anal_inference, anal_state='ING')
|
||||
* <li>각 회차별 처리 필요 여부 판단 (all_cnt != file_cnt)
|
||||
* <li>회차마다 Child Job(processAnalCntInfoJob) 실행
|
||||
* <li>부분 실패 허용 (한 회차 실패해도 다른 회차 계속 처리)
|
||||
* <li>진행 중인 분석 회차 목록 조회 (tb_map_sheet_anal_inference, anal_state='ING')
|
||||
* <li>각 회차별 처리 필요 여부 판단 (all_cnt != file_cnt)
|
||||
* <li>회차마다 Child Job(processAnalCntInfoJob) 실행
|
||||
* <li>부분 실패 허용 (한 회차 실패해도 다른 회차 계속 처리)
|
||||
* </ul>
|
||||
*
|
||||
* <p><b>실행 조건:</b>
|
||||
* <p>
|
||||
* <b>실행 조건:</b>
|
||||
*
|
||||
* <ul>
|
||||
* <li>tb_map_sheet_anal_inference.anal_state = 'ING' (진행 중)
|
||||
* <li>검수 완료 건수(complete_cnt) > 0
|
||||
* <li>all_cnt != file_cnt (아직 파일 생성이 완료되지 않음)
|
||||
* <li>tb_map_sheet_anal_inference.anal_state = 'ING' (진행 중)
|
||||
* <li>검수 완료 건수(complete_cnt) > 0
|
||||
* <li>all_cnt != file_cnt (아직 파일 생성이 완료되지 않음)
|
||||
* </ul>
|
||||
*
|
||||
* <p><b>실패 정책:</b>
|
||||
* <p>
|
||||
* <b>실패 정책:</b>
|
||||
*
|
||||
* <ul>
|
||||
* <li>현재: 부분 실패 허용 (일부 Child Job 실패해도 Parent Job 성공)
|
||||
* <li>변경 가능: 87-89라인 주석 해제 시 하나라도 실패하면 Parent Job 실패
|
||||
* <li>현재: 부분 실패 허용 (일부 Child Job 실패해도 Parent Job 성공)
|
||||
* <li>변경 가능: 87-89라인 주석 해제 시 하나라도 실패하면 Parent Job 실패
|
||||
* </ul>
|
||||
*
|
||||
* @author KAMCO Development Team
|
||||
@@ -69,10 +78,15 @@ public class LaunchChildJobsTasklet implements Tasklet {
|
||||
@Qualifier("processAnalCntInfoJob")
|
||||
private final Job processAnalCntInfoJob;
|
||||
|
||||
/** 트랜잭션 매니저 (트랜잭션 제어용) */
|
||||
private final PlatformTransactionManager transactionManager;
|
||||
|
||||
/**
|
||||
* Parent Job의 메인 로직 실행
|
||||
*
|
||||
* <p>진행 중인 모든 분석 회차를 조회하여 각 회차마다 Child Job을 실행합니다. 한 회차가 실패해도 다른 회차는 계속 처리되며, 최종적으로 통계를
|
||||
* <p>
|
||||
* 진행 중인 모든 분석 회차를 조회하여 각 회차마다 Child Job을 실행합니다. 한 회차가 실패해도 다른 회차는 계속 처리되며,
|
||||
* 최종적으로 통계를
|
||||
* 로깅합니다.
|
||||
*
|
||||
* @param contribution Step 실행 정보를 담는 객체
|
||||
@@ -133,12 +147,11 @@ public class LaunchChildJobsTasklet implements Tasklet {
|
||||
|
||||
try {
|
||||
// Child Job Parameters 생성
|
||||
JobParameters jobParameters =
|
||||
new JobParametersBuilder()
|
||||
.addLong("analUid", info.getAnalUid())
|
||||
.addString("resultUid", info.getResultUid())
|
||||
.addLong("timestamp", System.currentTimeMillis()) // JobInstance 고유성 보장
|
||||
.toJobParameters();
|
||||
JobParameters jobParameters = new JobParametersBuilder()
|
||||
.addLong("analUid", info.getAnalUid())
|
||||
.addString("resultUid", info.getResultUid())
|
||||
.addLong("timestamp", System.currentTimeMillis()) // JobInstance 고유성 보장
|
||||
.toJobParameters();
|
||||
|
||||
log.info("[Child Job 실행] processAnalCntInfoJob 시작...");
|
||||
log.info(" - JobParameters: analUid={}, resultUid={}", info.getAnalUid(),
|
||||
@@ -148,7 +161,21 @@ public class LaunchChildJobsTasklet implements Tasklet {
|
||||
// asyncJobLauncher를 사용하여 별도 쓰레드에서 실행
|
||||
// 내부적으로 makeGeoJsonStep → dockerRunStep → zipResponseStep 순차 실행
|
||||
long startTime = System.currentTimeMillis();
|
||||
JobExecution jobExecution = asyncJobLauncher.run(processAnalCntInfoJob, jobParameters);
|
||||
|
||||
// 트랜잭션 일시 정지 후 실행 (Existing transaction detected 에러 방지)
|
||||
JobExecution jobExecution = new TransactionTemplate(transactionManager,
|
||||
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_NOT_SUPPORTED))
|
||||
.execute(status -> {
|
||||
try {
|
||||
return asyncJobLauncher.run(processAnalCntInfoJob, jobParameters);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
if (jobExecution == null) {
|
||||
throw new RuntimeException("JobExecution is null after launching child job");
|
||||
}
|
||||
|
||||
// Child Job 완료 대기 (비동기 실행이므로 완료를 폴링)
|
||||
log.info("[Child Job 대기] 실행 완료 대기 중... (JobExecutionId={})",
|
||||
@@ -222,8 +249,7 @@ public class LaunchChildJobsTasklet implements Tasklet {
|
||||
|
||||
// 성공률 계산
|
||||
if (analList.size() > 0) {
|
||||
double successRate =
|
||||
(double) processedCount / (analList.size() - skippedCount) * 100;
|
||||
double successRate = (double) processedCount / (analList.size() - skippedCount) * 100;
|
||||
log.info(" - 성공률: {}% (건너뛴 회차 제외)", String.format("%.2f", successRate));
|
||||
}
|
||||
|
||||
@@ -239,8 +265,8 @@ public class LaunchChildJobsTasklet implements Tasklet {
|
||||
// 실패가 있어도 Parent Job은 성공으로 처리 (부분 성공 정책)
|
||||
// 만약 하나라도 실패하면 Parent Job도 실패로 처리하려면 아래 주석 해제
|
||||
// throw new RuntimeException(
|
||||
// String.format("%d 개의 Child Job 실행이 실패했습니다. (성공: %d, 실패: %d)",
|
||||
// failedCount, processedCount, failedCount));
|
||||
// String.format("%d 개의 Child Job 실행이 실패했습니다. (성공: %d, 실패: %d)",
|
||||
// failedCount, processedCount, failedCount));
|
||||
} else {
|
||||
log.info("[완료] 모든 Child Job이 정상적으로 완료되었습니다.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user