status-update 로직 수정

This commit is contained in:
2026-03-12 13:39:34 +09:00
parent 9f99aa78a4
commit 71916cc80c
18 changed files with 112 additions and 4 deletions

View File

@@ -650,7 +650,7 @@ code + .copy-button {
<script type="text/javascript"> <script type="text/javascript">
function configurationCacheProblems() { return ( function configurationCacheProblems() { return (
// begin-report-data // begin-report-data
{"diagnostics":[{"locations":[{}],"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10.0."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/8.14/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('url = <value>') instead."}]]},{"locations":[{"path":"C:\\workspace\\kamco-cd-cron\\gukyuin\\status-update\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\config\\resttemplate\\ExternalHttpClient.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Some input files use or override a deprecated API."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Some input files use or override a deprecated API."}],"contextualLabel":"Some input files use or override a deprecated API.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.plural","displayName":"Some input files use or override a deprecated API."}]},{"locations":[{"path":"C:\\workspace\\kamco-cd-cron\\gukyuin\\status-update\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\config\\resttemplate\\ExternalHttpClient.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Recompile with -Xlint:deprecation for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:deprecation for details."}],"contextualLabel":"Recompile with -Xlint:deprecation for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.recompile","displayName":"Recompile with -Xlint:deprecation for details."}]},{"locations":[{"path":"C:\\workspace\\kamco-cd-cron\\gukyuin\\status-update\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\common\\utils\\enums\\Enums.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Some input files use unchecked or unsafe operations."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Some input files use unchecked or unsafe operations."}],"contextualLabel":"Some input files use unchecked or unsafe operations.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.unchecked.plural","displayName":"Some input files use unchecked or unsafe operations."}]},{"locations":[{"path":"C:\\workspace\\kamco-cd-cron\\gukyuin\\status-update\\src\\main\\java\\com\\kamco\\cd\\kamcoback\\common\\utils\\enums\\Enums.java"},{"taskPath":":compileJava"}],"problem":[{"text":"Recompile with -Xlint:unchecked for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:unchecked for details."}],"contextualLabel":"Recompile with -Xlint:unchecked for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.unchecked.recompile","displayName":"Recompile with -Xlint:unchecked for details."}]}],"problemsReport":{"totalProblemCount":5,"buildName":"kamco-status-update-job","requestedTasks":"clean build","documentationLink":"https://docs.gradle.org/8.14/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}} {"diagnostics":[{"locations":[{}],"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10.0."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/8.14/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('url = <value>') instead."}]]}],"problemsReport":{"totalProblemCount":1,"buildName":"kamco-status-update-job","requestedTasks":":classes :testClasses","documentationLink":"https://docs.gradle.org/8.14/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}}
// end-report-data // end-report-data
);} );}
</script> </script>

View File

@@ -1,9 +1,11 @@
package com.kamco.cd.kamcoback.postgres.core; package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.postgres.repository.gukyuin.GukYuinPnuCntUpdateJobRepository; import com.kamco.cd.kamcoback.postgres.repository.gukyuin.GukYuinPnuCntUpdateJobRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Service @Service
public class GukYuinPnuCntUpdateJobCoreService { public class GukYuinPnuCntUpdateJobCoreService {
@@ -23,4 +25,14 @@ public class GukYuinPnuCntUpdateJobCoreService {
public void updateGukYuinApplyStatus(String uid, String status) { public void updateGukYuinApplyStatus(String uid, String status) {
gukYuinPnuCntUpdateRepository.updateGukYuinApplyStatus(uid, status); gukYuinPnuCntUpdateRepository.updateGukYuinApplyStatus(uid, status);
} }
public long[] findGeoUidRange(String uid) {
return gukYuinPnuCntUpdateRepository.findGeoUidRange(uid);
}
public int updateRangeBatch(long start, long end, int batchSize, int loop) {
int updated = gukYuinPnuCntUpdateRepository.updateRangeBatch(start, end, batchSize);
log.info("PNU batch loop={}, range=[{},{}], updated={}", loop, start, end, updated);
return updated;
}
} }

View File

@@ -5,4 +5,8 @@ public interface GukYuinPnuCntUpdateJobRepositoryCustom {
int updateGukYuinContListPnuUpdateCnt(); int updateGukYuinContListPnuUpdateCnt();
void updateGukYuinApplyStatus(String uid, String status); void updateGukYuinApplyStatus(String uid, String status);
long[] findGeoUidRange(String uid);
int updateRangeBatch(long startGeoUid, long endGeoUid, int batchSize);
} }

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.postgres.repository.gukyuin; package com.kamco.cd.kamcoback.postgres.repository.gukyuin;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnEntity.mapSheetLearnEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnEntity.mapSheetLearnEntity;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
@@ -49,4 +50,60 @@ public class GukYuinPnuCntUpdateJobRepositoryImpl
.where(mapSheetLearnEntity.uid.eq(uid)) .where(mapSheetLearnEntity.uid.eq(uid))
.execute(); .execute();
} }
@Override
public long[] findGeoUidRange(String uid) {
Long analUid =
queryFactory
.select(mapSheetAnalInferenceEntity.id)
.from(mapSheetLearnEntity)
.innerJoin(mapSheetAnalInferenceEntity)
.on(mapSheetLearnEntity.id.eq(mapSheetAnalInferenceEntity.learnId))
.where(mapSheetLearnEntity.uid.eq(uid))
.fetchOne();
if (analUid != null) {
String sql =
"""
select min(gt.geo_uid), max(gt.geo_uid)
from tb_map_sheet_anal_inference inf
inner join tb_map_sheet_anal_data_inference dt
on(inf.anal_uid = dt.anal_uid)
inner join tb_map_sheet_anal_data_inference_geom gt
on(dt.data_uid = gt.data_uid)
where inf.anal_uid = ?
""";
return jdbcTemplate.queryForObject(
sql, (rs, rowNum) -> new long[] {rs.getLong(1), rs.getLong(2)}, analUid);
}
return new long[0];
}
@Override
public int updateRangeBatch(long startGeoUid, long endGeoUid, int batchSize) {
String sql =
"""
WITH batch AS (
SELECT p.geo_uid
FROM tb_map_sheet_anal_data_inference_geom p
WHERE p.pnu IS DISTINCT FROM 1
AND EXISTS (
SELECT 1
FROM tb_pnu tp
WHERE tp.geo_uid = p.geo_uid
)
AND p.geo_uid >= ?
AND p.geo_uid <= ?
LIMIT ?
)
UPDATE tb_map_sheet_anal_data_inference_geom p
SET pnu = 1
FROM batch
WHERE p.geo_uid = batch.geo_uid
""";
return jdbcTemplate.update(sql, startGeoUid, endGeoUid, batchSize);
}
} }

View File

@@ -91,10 +91,45 @@ public class GukYuinApiStatusJobService {
log.info("[Step 5] progress 100 확인 → PNU CNT update 실행"); log.info("[Step 5] progress 100 확인 → PNU CNT update 실행");
log.info( log.info(
"=== tb_pnu 에 insert 된 데이터 중 tb_map_sheet_anal_data_inference_geom 의 pnu (cnt)값이 다른 것 update"); "=== tb_pnu 에 insert 된 데이터 중 tb_map_sheet_anal_data_inference_geom 의 pnu 값이 있는 것 1로 update");
int updateCnt = gukYuinPnuCntUpdateJobCoreService.updateGukYuinContListPnuUpdateCnt(); long[] range = gukYuinPnuCntUpdateJobCoreService.findGeoUidRange(dto.getUid());
long min = range[0];
long max = range[1];
long rangeSize = 500000; // geo_uid 범위
int batchSize = 10000;
log.info("[Step 5] 회차에 geo_uid의 min, max 를 구해서 그 값만 조회해서 batchSize 만큼 Loop를 돌리게 한다.");
log.info("PNU batch start min={}, max={}", min, max);
for (long start = min; start <= max; start += rangeSize) {
long end = Math.min(start + rangeSize - 1, max);
log.info("Processing range {} ~ {}", start, end);
int loop = 0;
while (true) {
loop++;
int updated =
gukYuinPnuCntUpdateJobCoreService.updateRangeBatch(start, end, batchSize, loop);
if (updated == 0) {
break;
}
}
}
log.info("PNU batch finished");
// int updateCnt =
// gukYuinPnuCntUpdateJobCoreService.updateGukYuinContListPnuUpdateCnt();
// log.info("[Step 5] PNU CNT update 완료 updatedRows={}", updateCnt);
log.info("[Step 5] PNU CNT update 완료 updatedRows={}", updateCnt);
log.info( log.info(
"[Step 6] 추론 learn 테이블 apply_status={} 로 업데이트", GukYuinStatus.PNU_COMPLETED.getId()); "[Step 6] 추론 learn 테이블 apply_status={} 로 업데이트", GukYuinStatus.PNU_COMPLETED.getId());
gukYuinPnuCntUpdateJobCoreService.updateGukYuinApplyStatus( gukYuinPnuCntUpdateJobCoreService.updateGukYuinApplyStatus(