Add Ship Detail Sync Job

This commit is contained in:
hyojin kim 2026-01-09 16:07:00 +09:00
부모 1ab78e881f
커밋 9c021f298c

파일 보기

@ -0,0 +1,150 @@
package com.snp.batch.jobs.shipdetail.batch.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Configuration
public class ShipDetailSyncJobConfig {
private final JobRepository jobRepository;
private final PlatformTransactionManager transactionManager;
private final JdbcTemplate jdbcTemplate;
// API 정의 (배치 로그 관리용)
protected String getApiKey() {
return "SHIP_DETAIL_SYNC_API";
}
// 마지막 실행 일자 업데이트 SQL
protected String getBatchUpdateSql() {
return String.format(
"UPDATE SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'",
getApiKey()
);
}
public ShipDetailSyncJobConfig(
JobRepository jobRepository,
PlatformTransactionManager transactionManager,
JdbcTemplate jdbcTemplate) {
this.jobRepository = jobRepository;
this.transactionManager = transactionManager;
this.jdbcTemplate = jdbcTemplate;
}
/**
* 동기화 대상 25개 테이블 리스트
*/
private static final List<String> SYNC_TABLES = Arrays.asList(
"additionalshipsdata", "bareboatcharterhistory",
"callsignandmmsihistory", "classhistory", "companycompliancedetails",
"companyvesselrelationships", "crewlist", "darkactivityconfirmed",
"flaghistory", "groupbeneficialownerhistory", "iceclass", "namehistory",
"operatorhistory", "ownerhistory", "pandihistory", "safetymanagementcertificatehist",
"shipmanagerhistory", "sistershiplinks", "specialfeature", "statushistory",
"stowagecommodity", "surveydates", "surveydateshistoryunique",
"technicalmanagerhistory", "thrusters"
);
/**
* Job 구성: 모든 테이블 동기화 마지막 업데이트 실행
*/
@Bean(name = "ShipDetailSyncJob")
public Job shipDetailSyncJob() {
return new JobBuilder("ShipDetailSyncJob", jobRepository)
.start(shipMasterAndCoreSyncStep()) // 1단계: Ship_Detail_Data, Core20 테이블 동기화
.next(shipDetailSyncStep()) // 2단계: 선박제원정보 종속 25개 테이블 순차 동기화
.next(shipDetailSyncLastExecutionUpdateStep()) // 3단계: 최종 성공 시간 업데이트
.build();
}
/**
* 1단계: Ship_Detail_Data, Core20 테이블 동기화
*/
@Bean
public Tasklet shipMasterAndCoreSyncTasklet() {
return (contribution, chunkContext) -> {
log.info(">>>>> SHIP MASTER & CORE20 동기화 프로시저 호출 시작");
// PostgreSQL 기준 프로시저 호출 (CALL)
jdbcTemplate.execute("CALL snp_data.proc_sync_ship_master_and_core()");
log.info(">>>>> SHIP MASTER & CORE20 동기화 프로시저 호출 완료");
return RepeatStatus.FINISHED;
};
}
@Bean(name = "ShipMasterAndCoreSyncStep")
public Step shipMasterAndCoreSyncStep() {
return new StepBuilder("ShipMasterAndCoreSyncStep", jobRepository)
.tasklet(shipMasterAndCoreSyncTasklet(), transactionManager)
.build();
}
/**
* 2단계: 25개 테이블 동기화 Tasklet
*/
@Bean
public Tasklet shipDetailSyncTasklet() {
return (contribution, chunkContext) -> {
log.info(">>>>> [시작] 25개 테이블 동기화 프로세스");
for (String tableName : SYNC_TABLES) {
try {
log.info("테이블 동기화 중: {}", tableName);
// 이전에 생성한 동적 프로시저 호출
jdbcTemplate.execute("CALL snp_data.proc_sync_ship_detail('" + tableName + "')");
} catch (Exception e) {
log.error("테이블 동기화 실패: {}. 에러: {}", tableName, e.getMessage());
// 특정 테이블 실패 중단할지, 계속 진행할지에 따라 throw 여부 결정
throw e; // 중단하려면 주석 해제
}
}
log.info(">>>>> [완료] 25개 테이블 동기화 프로세스");
return RepeatStatus.FINISHED;
};
}
@Bean(name = "ShipDetailSyncStep")
public Step shipDetailSyncStep() {
return new StepBuilder("ShipDetailSyncStep", jobRepository)
.tasklet(shipDetailSyncTasklet(), transactionManager)
.build();
}
/**
* 3단계: 모든 스텝 성공 배치 실행 로그 업데이트
*/
@Bean
public Tasklet shipDetailSyncLastExecutionUpdateTasklet() {
return (contribution, chunkContext) -> {
log.info(">>>>> 모든 테이블 동기화 성공: BATCH_LAST_EXECUTION 업데이트 시작");
jdbcTemplate.execute(getBatchUpdateSql());
log.info(">>>>> BATCH_LAST_EXECUTION 업데이트 완료");
return RepeatStatus.FINISHED;
};
}
@Bean(name = "ShipDetailSyncLastExecutionUpdateStep")
public Step shipDetailSyncLastExecutionUpdateStep() {
return new StepBuilder("ShipDetailSyncLastExecutionUpdateStep", jobRepository)
.tasklet(shipDetailSyncLastExecutionUpdateTasklet(), transactionManager)
.build();
}
}