ObpGwMetric UK 문제 수정
This commit is contained in:
@@ -12,6 +12,7 @@ import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricService;
|
|||||||
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricVO;
|
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricVO;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -185,40 +186,59 @@ public class ObpGwMetricManService extends BaseService {
|
|||||||
|
|
||||||
int insertCount = 0;
|
int insertCount = 0;
|
||||||
int updateCount = 0;
|
int updateCount = 0;
|
||||||
|
int conflictRetryCount = 0;
|
||||||
|
|
||||||
for (ObpGwMetricVO vo : aggregatedList) {
|
for (ObpGwMetricVO vo : aggregatedList) {
|
||||||
LocalDateTime timesliceDateTime = vo.getTimesliceAsLocalDateTime();
|
LocalDateTime timesliceDateTime = vo.getTimesliceAsLocalDateTime();
|
||||||
|
|
||||||
Optional<ObpGwMetric> existing = obpGwMetricService.findByUniqueKey(
|
try {
|
||||||
timesliceDateTime,
|
Optional<ObpGwMetric> existing = obpGwMetricService.findByUniqueKey(
|
||||||
vo.getApiId(),
|
timesliceDateTime,
|
||||||
vo.getClientId(),
|
vo.getApiId(),
|
||||||
vo.getHostname(),
|
vo.getClientId(),
|
||||||
vo.getOrgId()
|
vo.getHostname(),
|
||||||
);
|
vo.getOrgId()
|
||||||
|
);
|
||||||
|
|
||||||
if (existing.isPresent()) {
|
if (existing.isPresent()) {
|
||||||
// UPDATE: 기존 데이터 갱신
|
// UPDATE: 기존 데이터 갱신
|
||||||
ObpGwMetric entity = existing.get();
|
updateExistingMetric(existing.get(), vo, apiNameMap, uriMap, methodMap, appIdMap);
|
||||||
entity.setAttemptedCount(vo.getAttemptedCount());
|
updateCount++;
|
||||||
entity.setCompletedCount(vo.getCompletedCount());
|
} else {
|
||||||
entity.setApiName(apiNameMap.get(vo.getApiId()));
|
// INSERT: 신규 데이터 생성
|
||||||
entity.setUri(uriMap.get(vo.getEaiSvcSerno())); // eaiSvcSerno로 URI 조회
|
ObpGwMetric entity = convertToEntity(vo, apiNameMap, uriMap, methodMap, appIdMap);
|
||||||
entity.setMethod(methodMap.get(vo.getEaiSvcSerno())); // eaiSvcSerno로 HTTP Method 조회
|
obpGwMetricService.save(entity);
|
||||||
entity.setAppId(appIdMap.get(vo.getOrgId()));
|
insertCount++;
|
||||||
entity.setUpdateCount(entity.getUpdateCount() + 1); // 보정 횟수 증가
|
}
|
||||||
entity.setUpdatedAt(LocalDateTime.now());
|
} catch (DataIntegrityViolationException e) {
|
||||||
entity.setUpdatedBy("GwMetricHourJob");
|
// Unique constraint violation 발생 시 UPDATE로 재시도
|
||||||
obpGwMetricService.save(entity);
|
log.debug("UK 충돌 발생, UPDATE로 재시도: timeslice={}, apiId={}, clientId={}",
|
||||||
updateCount++;
|
timesliceDateTime, vo.getApiId(), vo.getClientId());
|
||||||
} else {
|
|
||||||
// INSERT: 신규 데이터 생성
|
Optional<ObpGwMetric> existing = obpGwMetricService.findByUniqueKey(
|
||||||
ObpGwMetric entity = convertToEntity(vo, apiNameMap, uriMap, methodMap, appIdMap);
|
timesliceDateTime,
|
||||||
obpGwMetricService.save(entity);
|
vo.getApiId(),
|
||||||
insertCount++;
|
vo.getClientId(),
|
||||||
|
vo.getHostname(),
|
||||||
|
vo.getOrgId()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (existing.isPresent()) {
|
||||||
|
updateExistingMetric(existing.get(), vo, apiNameMap, uriMap, methodMap, appIdMap);
|
||||||
|
updateCount++;
|
||||||
|
conflictRetryCount++;
|
||||||
|
} else {
|
||||||
|
// 재조회에서도 없으면 예외 재발생 (비정상 상황)
|
||||||
|
log.error("UK 충돌 후 재조회 실패: timeslice={}, apiId={}", timesliceDateTime, vo.getApiId());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conflictRetryCount > 0) {
|
||||||
|
log.info("[4단계] UK 충돌 재시도 건수: {}", conflictRetryCount);
|
||||||
|
}
|
||||||
|
|
||||||
log.info("[4단계] UPSERT 완료: INSERT={}, UPDATE={}, elapsed={}ms",
|
log.info("[4단계] UPSERT 완료: INSERT={}, UPDATE={}, elapsed={}ms",
|
||||||
insertCount, updateCount, System.currentTimeMillis() - step4Start);
|
insertCount, updateCount, System.currentTimeMillis() - step4Start);
|
||||||
|
|
||||||
@@ -247,6 +267,26 @@ public class ObpGwMetricManService extends BaseService {
|
|||||||
return existing;
|
return existing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 기존 엔티티 업데이트
|
||||||
|
*/
|
||||||
|
private void updateExistingMetric(ObpGwMetric entity, ObpGwMetricVO vo,
|
||||||
|
Map<String, String> apiNameMap,
|
||||||
|
Map<String, String> uriMap,
|
||||||
|
Map<String, String> methodMap,
|
||||||
|
Map<String, String> appIdMap) {
|
||||||
|
entity.setAttemptedCount(vo.getAttemptedCount());
|
||||||
|
entity.setCompletedCount(vo.getCompletedCount());
|
||||||
|
entity.setApiName(apiNameMap.get(vo.getApiId()));
|
||||||
|
entity.setUri(uriMap.get(vo.getEaiSvcSerno()));
|
||||||
|
entity.setMethod(methodMap.get(vo.getEaiSvcSerno()));
|
||||||
|
entity.setAppId(appIdMap.get(vo.getOrgId()));
|
||||||
|
entity.setUpdateCount(entity.getUpdateCount() + 1);
|
||||||
|
entity.setUpdatedAt(LocalDateTime.now());
|
||||||
|
entity.setUpdatedBy("GwMetricHourJob");
|
||||||
|
obpGwMetricService.save(entity);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VO → Entity 변환
|
* VO → Entity 변환
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.eactive.eai.rms.common.context.MonitoringContext;
|
|||||||
import com.eactive.eai.rms.common.util.CommonUtil;
|
import com.eactive.eai.rms.common.util.CommonUtil;
|
||||||
import com.eactive.eai.rms.onl.apim.obp.ObpGwMetricManService;
|
import com.eactive.eai.rms.onl.apim.obp.ObpGwMetricManService;
|
||||||
import com.eactive.eai.rms.onl.common.util.DateUtil;
|
import com.eactive.eai.rms.onl.common.util.DateUtil;
|
||||||
|
import org.quartz.DisallowConcurrentExecution;
|
||||||
import org.quartz.Job;
|
import org.quartz.Job;
|
||||||
import org.quartz.JobDataMap;
|
import org.quartz.JobDataMap;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
@@ -41,6 +42,7 @@ import org.springframework.context.ApplicationContext;
|
|||||||
* jobDataMap.put("aggregation.hour.range", "3");
|
* jobDataMap.put("aggregation.hour.range", "3");
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
|
@DisallowConcurrentExecution
|
||||||
public class ObpGwMetricHourJob implements Job {
|
public class ObpGwMetricHourJob implements Job {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ObpGwMetricHourJob.class);
|
private static final Logger log = LoggerFactory.getLogger(ObpGwMetricHourJob.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user