HANTE 3 сар өмнө
parent
commit
0686cf4f6b
22 өөрчлөгдсөн 261 нэмэгдсэн , 521 устгасан
  1. 1 0
      .idea/inspectionProfiles/Project_Default.xml
  2. 1 1
      conf/utic-traf-server-trace.cfg
  3. 1 1
      utic-ptis-server/src/main/resources/mybatis/mapper/UticPtisServerMapper.xml
  4. 1 3
      utic-stat-server/src/main/java/com/utic/center/utic/stat/server/service/UticStatParamService.java
  5. 14 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/UticTrafServerApplication.java
  6. 9 13
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/controller/UticTrafServerController.java
  7. 2 3
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/controller/UticTrafServerRestController.java
  8. 5 3
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/mapper/dwdb/DwdbTrafficMapper.java
  9. 7 9
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/mapper/utic/UticTrafficMapper.java
  10. 11 13
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/repository/dwdb/DwdbTrafficRepository.java
  11. 19 22
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/repository/utic/UticTrafficRepository.java
  12. 18 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/DataCountDto.java
  13. 18 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/ViewTextDto.java
  14. 59 5
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/repository/ApplicationRepository.java
  15. 18 1
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafPrcsAfterService.java
  16. 0 104
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveCenterService.java
  17. 11 137
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveDwdbService.java
  18. 10 6
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveUticService.java
  19. 12 7
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/worker/LinkTrafSaveUticWorker.java
  20. 3 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/worker/WorkerUtils.java
  21. 15 106
      utic-traf-server/src/main/resources/mybatis/mapper/dwdb/DwdbTrafficMapper.xml
  22. 26 87
      utic-traf-server/src/main/resources/mybatis/mapper/utic/UticTrafficMapper.xml

+ 1 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -6,5 +6,6 @@
         <language minSize="64" name="Java" />
       </Languages>
     </inspection_tool>
+    <inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
   </profile>
 </component>

+ 1 - 1
conf/utic-traf-server-trace.cfg

@@ -1,2 +1,2 @@
 debug=false
-linkIds=1960162800,1960163000
+linkIds=

+ 1 - 1
utic-ptis-server/src/main/resources/mybatis/mapper/UticPtisServerMapper.xml

@@ -100,7 +100,7 @@
              LINK@UTIS           LK
         WHERE ST.LINKLEVEL = '1'
           AND ST.LINKID = LK.LINKID
-          AND ST.MISSVALUEYN IN ('R', 'K', 'H', 'L')
+          AND ST.MISSVALUEYN IN ('R', 'K', 'H', 'L', 'Y', 'O')
           AND (
             (LK.ROADRANK IN ('102', '104', '105' , '106' , '107'))
                 OR

+ 1 - 3
utic-stat-server/src/main/java/com/utic/center/utic/stat/server/service/UticStatParamService.java

@@ -68,6 +68,7 @@ public class UticStatParamService implements AbstractProcessService {
     }
 
     // 내부 static enum 선언
+    @Getter
     public static enum CodeValueKey {
         CODE_00("C01T01"), // 표준편차 필터링
         CODE_01("C01T02"), // 통계기준치 필터링
@@ -94,9 +95,6 @@ public class UticStatParamService implements AbstractProcessService {
             this.key = key;
         }
 
-        public String getKey() {
-            return key;
-        }
     }
 
 }

+ 14 - 0
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/UticTrafServerApplication.java

@@ -3,6 +3,9 @@ package com.utic.center.utic.traf.server;
 import com.utic.center.common.spring.SpringUtils;
 import com.utic.center.common.utils.ApplicationUtils;
 import com.utic.center.utic.traf.server.config.ApplicationConfig;
+import com.utic.center.utic.traf.server.dao.repository.utic.UticTrafficRepository;
+import com.utic.center.utic.traf.server.dto.ViewTextDto;
+import com.utic.center.utic.traf.server.repository.ApplicationRepository;
 import com.utic.center.utic.traf.server.service.LinkParamService;
 import com.utic.center.utic.traf.server.service.LinkPatternService;
 import com.utic.center.utic.traf.server.service.LinkService;
@@ -69,6 +72,17 @@ public class UticTrafServerApplication implements CommandLineRunner, Application
         ApplicationConfig applicationConfig = SpringUtils.getBean(ApplicationConfig.class);
         applicationConfig.setStartSchedule(false);
 
+        // TRAFFIC_CENTER VIEW ACTIVE TABLE Checking
+        UticTrafficRepository repo = SpringUtils.getBean(UticTrafficRepository.class);
+        ViewTextDto activeView = repo.findTrafficCenterViewDdl();
+        if (activeView == null) {
+            log.error("UticTrafServerApplication.run: loading traffic_center view checking Failed. program shutdown.");
+            SpringApplication.exit(SpringUtils.getApplicationContext());
+            System.exit(0);
+            return;
+        }
+        ApplicationRepository.setCurrentTrafficCenterView(activeView.getViewText());
+
         // 프로세스 상태 저장
         ProcessStateService processStateService = SpringUtils.getBean(ProcessStateService.class);
         processStateService.processStart();

+ 9 - 13
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/controller/UticTrafServerController.java

@@ -27,8 +27,7 @@ public class UticTrafServerController {
     private final LinkTrafCollectService collectService;
     private final LinkTrafFusionService fusionService;
     private final LinkTrafMissingService missingService;
-    private final LinkTrafSaveCacheService saveCacheService;
-    private final LinkTrafSaveCenterService saveCenterService;
+    private final LinkTrafSaveUticService saveUticService;
     private final LinkTrafSaveDwdbService saveDwdbService;
     private final LinkTrafPrcsDebugService debugService;
 
@@ -116,38 +115,35 @@ public class UticTrafServerController {
 
             // 4. 소통정보 저장(TRAFFIC_CENTER_CACHE) 작업
             tmpStart = System.currentTimeMillis();
-            this.saveCacheService.processing();
-            jobInfo.setSaveCacheTime(System.currentTimeMillis() - tmpStart);
-            log.info(step);
-
-            // 5. 소통정보 저장(TRAFFIC_CENTER_CACHE ==> TRAFFIC_CENTER) 작업
-            tmpStart = System.currentTimeMillis();
-            this.saveCenterService.processing();
+            this.saveUticService.processing();
             jobInfo.setSaveCenterTime(System.currentTimeMillis() - tmpStart);
             jobInfo.setSaveTrafficTime(System.currentTimeMillis() - start);
             log.info("##>> 05MIN {}", LogUtils.elapsedLogLength("정주기 교통정보 저장 완료", jobInfo.getSaveTrafficTime(), 5));
             log.info(completed);
 
-            // 6. DWDB 저장
+            // 5. DWDB 저장
             tmpStart = System.currentTimeMillis();
             this.saveDwdbService.processing();
             jobInfo.setSaveDwdbTime(System.currentTimeMillis() - tmpStart);
             log.info(step);
 
-            // 7. 디버그 정보 출력
+            // 6. 디버그 정보 출력
             this.debugService.processing();
 
-            // 8. 가공 기초정보 로딩 및 가공 후 처리
+            // 7. 가공 기초정보 로딩 및 가공 후 처리
             tmpStart = System.currentTimeMillis();
             this.prepareService.processing();
             jobInfo.setPrepareTime(System.currentTimeMillis() - tmpStart);
             log.info(step);
 
-            // 9. 가공 후 처리
+            // 8. 가공 후 처리
             tmpStart = System.currentTimeMillis();
             this.prcsAfterService.processing();
             jobInfo.setPrcsAfterTime(System.currentTimeMillis() - tmpStart);
             log.info(step);
+
+            // 제일 마지막에 처리
+            ApplicationRepository.swapTrafficCenterView();
         }
         finally {
             this.isRunning = false; // 현재 작업이 종료됨을 표시

+ 2 - 3
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/controller/UticTrafServerRestController.java

@@ -28,7 +28,7 @@ public class UticTrafServerRestController {
         sb.append(heading).append(sep);
         sb.append(String.format("Process Id: %s, %s, %s", this.config.getProcessId(), this.config.getBootingTime(), TimeUtils.now())).append(sep);
         sb.append(heading).append(sep);
-        sb.append(String.format("%s %-20.20s %-20.20s    TOTAL ASN_ETLP  COLLECT   FUSION  MISSING    CACHE   CENTER  TRAFFIC     DWDB  PREPARE    AFTER",
+        sb.append(String.format("%s %-20.20s %-20.20s    TOTAL RCV_TRAF  COLLECT   FUSION  MISSING UTIADMIN  TRAFFIC     DWDB  PREPARE    AFTER",
                 " SEQ", "Start", "End")).append(sep);
         sb.append(heading).append(sep);
         int total = 0;
@@ -38,7 +38,7 @@ public class UticTrafServerRestController {
             BatchJobInfoDto jobInfo = ApplicationRepository.batchJobInfoList.get(ii);
             total++;
 
-            sb.append(String.format("%4d %-20.20s %-20.20s %s %s %s %s %s %s %s %s %s %s %s",
+            sb.append(String.format("%4d %-20.20s %-20.20s %s %s %s %s %s %s %s %s %s %s",
                     total,
                     jobInfo.getStartTime(), jobInfo.getEndTime(),
                     LogUtils.numberLog(jobInfo.getElapsedTime()),
@@ -46,7 +46,6 @@ public class UticTrafServerRestController {
                     LogUtils.numberLog(jobInfo.getCollectTime()),
                     LogUtils.numberLog(jobInfo.getFusionTime()),
                     LogUtils.numberLog(jobInfo.getMissingTime()),
-                    LogUtils.numberLog(jobInfo.getSaveCacheTime()),
                     LogUtils.numberLog(jobInfo.getSaveCenterTime()),
                     LogUtils.numberLog(jobInfo.getSaveTrafficTime()),
                     LogUtils.numberLog(jobInfo.getSaveDwdbTime()),

+ 5 - 3
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/mapper/dwdb/DwdbTrafficMapper.java

@@ -1,5 +1,6 @@
 package com.utic.center.utic.traf.server.dao.mapper.dwdb;
 
+import com.utic.center.utic.traf.server.dto.DataCountDto;
 import com.utic.center.utic.traf.server.dto.LinkMissingValueHistDto;
 import com.utic.center.utic.traf.server.dto.LinkTrafCenterDto;
 import com.utic.center.utic.traf.server.dto.LinkTrafFusionInfo;
@@ -8,7 +9,8 @@ import org.apache.ibatis.annotations.Param;
 
 @Mapper
 public interface DwdbTrafficMapper {
-    int insertTrafficCenterHist(@Param("obj") LinkTrafCenterDto obj);
-    int insertLinkFusionLog(@Param("obj") LinkTrafFusionInfo obj);
-    int insertLinkMissingValueHist(@Param("obj") LinkMissingValueHistDto obj);
+
+    DataCountDto findTrafficCenterHistDataExists(@Param("targetMonth") String targetMonth);
+    int truncateTrafficCenterHist(@Param("targetMonth") String targetMonth);
+    int insertTrafficCenterHist(@Param("targetMonth") String targetMonth, @Param("obj") LinkTrafCenterDto obj);
 }

+ 7 - 9
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/mapper/utic/UticTrafficMapper.java

@@ -2,24 +2,22 @@ package com.utic.center.utic.traf.server.dao.mapper.utic;
 
 import com.utic.center.utic.traf.server.dto.LinkTrafCenterDto;
 import com.utic.center.utic.traf.server.dto.TrafPrcsTimeDto;
+import com.utic.center.utic.traf.server.dto.ViewTextDto;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
 @Mapper
 public interface UticTrafficMapper {
 
+    ViewTextDto findNextMonth();
+    ViewTextDto findTrafficCenterViewDdl();
+
     TrafPrcsTimeDto findOneTrafPrcsTime();
     int truncateTrafficLoc();
     int insertCenterRecv(@Param("centerId") String centerId, @Param("infoType") String infoType, @Param("seq") Integer seq, @Param("dataCnt") Integer dataCnt);
 
-    int truncateTrafficCenterCache();
-    int insertTrafficCenterCache(@Param("obj") LinkTrafCenterDto obj);
-
-    int enableParallelDml();
-    int deleteTrafficCenter();
-    int insertTrafficCenter();
-
-    int mergeTrafficCenter();
-    int deleteTrafficCenterByDate(@Param("prcsTime") String prcsTime);
+    int truncateTrafficCenter(@Param("tableName") String tableName);
+    int insertTrafficCenter(@Param("tableName") String tableName, @Param("obj") LinkTrafCenterDto obj);
+    int swapTrafficCenterView(@Param("sourceTable") String sourceTable);
 
 }

+ 11 - 13
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/repository/dwdb/DwdbTrafficRepository.java

@@ -2,9 +2,8 @@ package com.utic.center.utic.traf.server.dao.repository.dwdb;
 
 import com.utic.center.common.annotation.SqlOperation;
 import com.utic.center.utic.traf.server.dao.mapper.dwdb.DwdbTrafficMapper;
-import com.utic.center.utic.traf.server.dto.LinkMissingValueHistDto;
+import com.utic.center.utic.traf.server.dto.DataCountDto;
 import com.utic.center.utic.traf.server.dto.LinkTrafCenterDto;
-import com.utic.center.utic.traf.server.dto.LinkTrafFusionInfo;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Repository;
 
@@ -14,18 +13,17 @@ public class DwdbTrafficRepository {
     
     private final DwdbTrafficMapper mapper;
 
-    @SqlOperation(type = SqlOperation.SqlType.INSERT, table = "LINK_FUSION_LOG")
-    public int insertLinkFusionLog(LinkTrafFusionInfo obj) {
-        return this.mapper.insertLinkFusionLog(obj);
+    @SqlOperation(type = SqlOperation.SqlType.SELECT, table = "TRAFFIC_CENTER_", param = "targetMonth")
+    public DataCountDto findTrafficCenterHistDataExists(String targetMonth) {
+        return this.mapper.findTrafficCenterHistDataExists(targetMonth);
     }
-
-    @SqlOperation(type = SqlOperation.SqlType.INSERT, table = "TRAFFIC_CENTER_HIST")
-    public int insertTrafficCenterHist(LinkTrafCenterDto obj) {
-        return this.mapper.insertTrafficCenterHist(obj);
+    @SqlOperation(type = SqlOperation.SqlType.TRUNCATE, table = "TRAFFIC_CENTER_", param = "targetMonth")
+    public int truncateTrafficCenterHist(String targetMonth) {
+        return this.mapper.truncateTrafficCenterHist(targetMonth);
     }
-
-    @SqlOperation(type = SqlOperation.SqlType.INSERT, table = "LINK_MISSING_VALUE_HIST")
-    public int insertLinkMissingValueHist(LinkMissingValueHistDto obj) {
-        return this.mapper.insertLinkMissingValueHist(obj);
+    @SqlOperation(type = SqlOperation.SqlType.INSERT, table = "TRAFFIC_CENTER_", param = "targetMonth")
+    public int insertTrafficCenterHist(String targetMonth, LinkTrafCenterDto obj) {
+        return this.mapper.insertTrafficCenterHist(targetMonth, obj);
     }
+
 }

+ 19 - 22
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/repository/utic/UticTrafficRepository.java

@@ -4,6 +4,7 @@ import com.utic.center.common.annotation.SqlOperation;
 import com.utic.center.utic.traf.server.dao.mapper.utic.UticTrafficMapper;
 import com.utic.center.utic.traf.server.dto.LinkTrafCenterDto;
 import com.utic.center.utic.traf.server.dto.TrafPrcsTimeDto;
+import com.utic.center.utic.traf.server.dto.ViewTextDto;
 import lombok.RequiredArgsConstructor;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
@@ -14,6 +15,15 @@ public class UticTrafficRepository {
 
     private final UticTrafficMapper mapper;
 
+    @SqlOperation(type = SqlOperation.SqlType.SELECT, table = "NEXT_MONTH(DUAL)")
+    public ViewTextDto findNextMonth() {
+        return this.mapper.findNextMonth();
+    }
+    @SqlOperation(type = SqlOperation.SqlType.SELECT, table = "USER_VIEWS")
+    public ViewTextDto findTrafficCenterViewDdl() {
+        return this.mapper.findTrafficCenterViewDdl();
+    }
+
     @SqlOperation(type = SqlOperation.SqlType.SELECT, table = "TRAF_PRCS_TIME")
     public TrafPrcsTimeDto findOneTrafPrcsTime() {
         return this.mapper.findOneTrafPrcsTime();
@@ -29,32 +39,19 @@ public class UticTrafficRepository {
         return this.mapper.insertCenterRecv(centerId, infoType, seq, dataCnt);
     }
 
-    @SqlOperation(type = SqlOperation.SqlType.TRUNCATE, table = "TRAFFIC_CENTER_CACHE")
-    public int truncateTrafficCenterCache() {
-        return this.mapper.truncateTrafficCenterCache();
+    @SqlOperation(type = SqlOperation.SqlType.TRUNCATE, table = "TRAFFIC_CENTER", param = "tableName")
+    public int truncateTrafficCenter(String tableName) {
+        return this.mapper.truncateTrafficCenter(tableName);
     }
 
-    @SqlOperation(type = SqlOperation.SqlType.INSERT, table = "TRAFFIC_CENTER_CACHE")
-    public int insertTrafficCenterCache(@Param("obj") LinkTrafCenterDto obj) {
-        return this.mapper.insertTrafficCenterCache(obj);
+    @SqlOperation(type = SqlOperation.SqlType.INSERT, table = "TRAFFIC_CENTER", param = "tableName")
+    public int insertTrafficCenter(String tableName, @Param("obj") LinkTrafCenterDto obj) {
+        return this.mapper.insertTrafficCenter(tableName, obj);
     }
 
-    @SqlOperation(type = SqlOperation.SqlType.DELETE, table = "TRAFFIC_CENTER")
-    public int deleteTrafficCenter() {
-        return this.mapper.deleteTrafficCenter();
+    @SqlOperation(type = SqlOperation.SqlType.UPDATE, table = "TRAFFIC_CENTER", param = "VIEW-SWAP", param2 = "sourceTable")
+    public int swapTrafficCenterView(String sourceTable) {
+        return this.mapper.swapTrafficCenterView(sourceTable);
     }
 
-    @SqlOperation(type = SqlOperation.SqlType.INSERT, table = "TRAFFIC_CENTER")
-    public int insertTrafficCenter() {
-        return this.mapper.insertTrafficCenter();
-    }
-
-    @SqlOperation(type = SqlOperation.SqlType.MERGE, table = "TRAFFIC_CENTER")
-    public int mergeTrafficCenter() {
-        return this.mapper.mergeTrafficCenter();
-    }
-    @SqlOperation(type = SqlOperation.SqlType.DELETE, table = "TRAFFIC_CENTER")
-    int deleteTrafficCenterByDate(@Param("prcsTime") String prcsTime) {
-        return this.mapper.deleteTrafficCenterByDate(prcsTime);
-    }
 }

+ 18 - 0
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/DataCountDto.java

@@ -0,0 +1,18 @@
+package com.utic.center.utic.traf.server.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@Builder
+@NoArgsConstructor//(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
+public class DataCountDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Integer dataCount;
+}

+ 18 - 0
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/ViewTextDto.java

@@ -0,0 +1,18 @@
+package com.utic.center.utic.traf.server.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@Builder
+@NoArgsConstructor//(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
+public class ViewTextDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String viewText;
+}

+ 59 - 5
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/repository/ApplicationRepository.java

@@ -1,6 +1,7 @@
 package com.utic.center.utic.traf.server.repository;
 
 import com.utic.center.common.dto.ProcessStateDto;
+import com.utic.center.common.utils.LogUtils;
 import com.utic.center.utic.traf.server.dto.BatchJobInfoDto;
 import com.utic.center.utic.traf.server.dto.TrafPrcsTimeDto;
 import lombok.Getter;
@@ -8,6 +9,8 @@ import lombok.extern.slf4j.Slf4j;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 @Slf4j
 @Getter
@@ -17,11 +20,8 @@ public class ApplicationRepository {
         throw new IllegalStateException("ApplicationRepository class");
     }
 
-    public static final String TABLE_TRAFFIC_CENTER_CACHE = "TRAFFIC_CENTER_CACHE";
-    public static final String TABLE_TRAFFIC_CENTER = "TMP_TRAFFIC_CENTER";
-    public static final String TABLE_TRAFFIC_CENTER_HIST = "TMP_TRAFFIC_CENTER_HIST@DWDB";
-    public static final String TABLE_LINK_MISSING_VALUE_HIST = "TMP_LINK_MISSING_VALUE_HIST@DWDB";
-//    public static final String TABLE_LINK_FUSION_LOG = "TMP_LINK_FUSION_LOG@DWDB";
+    public static final String TABLE_TRAFFIC_CENTER = "TRAFFIC_CENTER_";
+    public static final String TABLE_TRAFFIC_CENTER_HIST = "TRAFFIC_CENTER_";
 
     public static boolean isLoadingLink = false;
 
@@ -63,4 +63,58 @@ public class ApplicationRepository {
         batchJobInfoList.add(jobInfo);
     }
 
+    private static String extractTargetTable(String ddlText) {
+        if (ddlText == null || ddlText.isEmpty()) {
+            return null;
+        }
+        // 정규식으로 FROM 절에서 테이블명 추출
+        Pattern pattern = Pattern.compile("FROM\\s+(TRAFFIC_CENTER_[A-Z0-9_]+)", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(ddlText);
+        if (matcher.find()) {
+            return matcher.group(1).toUpperCase(); // 테이블명 반환
+        }
+        return null; // 매칭 실패
+    }
+
+    private static String getNextTargetTable(String currentTable) {
+        if ("TRAFFIC_CENTER_A".equalsIgnoreCase(currentTable)) {
+            return "TRAFFIC_CENTER_B";
+        } else if ("TRAFFIC_CENTER_B".equalsIgnoreCase(currentTable)) {
+            return "TRAFFIC_CENTER_A";
+        } else {
+            throw new IllegalArgumentException("알 수 없는 테이블명: " + currentTable);
+        }
+    }
+    private static String getSuffix(String tableName) {
+        int lastUnderscore = tableName.lastIndexOf('_');
+        if (lastUnderscore != -1 && lastUnderscore < tableName.length() - 1) {
+            return tableName.substring(lastUnderscore + 1);
+        }
+        return "A"; // 언더스코어가 없거나 잘못된 형식일 경우
+    }
+
+    public static String currTrafficCenter = "TRAFFIC_CENTER_A";
+    public static String nextTrafficCenter = "TRAFFIC_CENTER_B";
+
+    public static void setCurrentTrafficCenterView(String ddlText) {
+        currTrafficCenter = extractTargetTable(ddlText);
+        nextTrafficCenter = getNextTargetTable(currTrafficCenter);
+        logActiveView();
+    }
+    public static String getCurrTrafficCenterSuffix() {
+        return getSuffix(currTrafficCenter);
+    }
+    public static String getNextTrafficCenterSuffix() {
+        return getSuffix(nextTrafficCenter);
+    }
+    public static void swapTrafficCenterView() {
+        final String tmpTable = currTrafficCenter;
+        currTrafficCenter = nextTrafficCenter;
+        nextTrafficCenter = tmpTable;
+        logActiveView();
+    }
+
+    private static void logActiveView() {
+        log.info("[INF] {}: Active-{}, Next-{}", LogUtils.elapsedLog("TRAFFIC_CENTER(VIEW)"), currTrafficCenter, nextTrafficCenter);
+    }
 }

+ 18 - 1
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafPrcsAfterService.java

@@ -2,7 +2,11 @@ package com.utic.center.utic.traf.server.service;
 
 import com.utic.center.common.annotation.ProcessingElapsed;
 import com.utic.center.common.service.AbstractProcessService;
+import com.utic.center.utic.traf.server.dao.mapper.dwdb.DwdbTrafficMapper;
 import com.utic.center.utic.traf.server.dao.repository.utic.UticTrafficRepository;
+import com.utic.center.utic.traf.server.dto.DataCountDto;
+import com.utic.center.utic.traf.server.dto.ViewTextDto;
+import com.utic.center.utic.traf.server.repository.ApplicationRepository;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
@@ -17,13 +21,26 @@ import org.springframework.stereotype.Service;
 public class LinkTrafPrcsAfterService implements AbstractProcessService {
 
     private final UticTrafficRepository uticRepo;
+    private final DwdbTrafficMapper dwdbRepo;
 
     @ProcessingElapsed(type="PRCS", name="교통정보 준비 작업", starting = false)
     @Override
     public boolean processing() {
 
         this.uticRepo.truncateTrafficLoc();         // 지역 교통정보 테이블 초기화
-        this.uticRepo.truncateTrafficCenterCache(); // 캐시 테이블 초기화
+        this.uticRepo.truncateTrafficCenter(ApplicationRepository.currTrafficCenter); // 이전 소통정보 테이블 초기화
+
+        // DWDB TRAFFIC_CENTER_MM(TRAFFIC_CENTER_HIST) 초기화
+        // 다음달 테이블을 truncate 한다.
+        ViewTextDto nextMonth = this.uticRepo.findNextMonth();
+        if (nextMonth != null) {
+            DataCountDto dataCheck = this.dwdbRepo.findTrafficCenterHistDataExists(nextMonth.getViewText());
+            if (dataCheck != null) {
+                if (dataCheck.getDataCount() > 0) {
+                    this.dwdbRepo.truncateTrafficCenterHist(nextMonth.getViewText());
+                }
+            }
+        }
         return true;
     }
 }

+ 0 - 104
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveCenterService.java

@@ -1,104 +0,0 @@
-package com.utic.center.utic.traf.server.service;
-
-import com.utic.center.common.annotation.ProcessingElapsed;
-import com.utic.center.common.service.AbstractProcessService;
-import com.utic.center.common.utils.LogUtils;
-import com.utic.center.utic.traf.server.dao.mapper.utic.UticTrafficMapper;
-import com.utic.center.utic.traf.server.repository.ApplicationRepository;
-import lombok.Data;
-import lombok.RequiredArgsConstructor;
-import lombok.ToString;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.ibatis.session.ExecutorType;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.springframework.stereotype.Service;
-
-@Slf4j
-@Data
-@ToString
-@RequiredArgsConstructor
-@Service
-public class LinkTrafSaveCenterService implements AbstractProcessService {
-
-    private final SqlSessionFactory sqlSessionFactory;
-
-//    @ProcessingElapsed(type="TRAFFIC", name="교통정보 CENTER 저장", starting = false)
-//    @Override
-    public boolean processingMerge() {
-        final String tableName = ApplicationRepository.TABLE_TRAFFIC_CENTER;
-        try {
-            // 1. 세션 열기 (BATCH 모드 + 수동 커밋)
-            SqlSession sqlSession = this.sqlSessionFactory.openSession(ExecutorType.BATCH, false);
-            UticTrafficMapper mapper = sqlSession.getMapper(UticTrafficMapper.class);
-
-            // 2. MERGE 수행
-            int insertCount = mapper.mergeTrafficCenter();
-            if (insertCount == -2147482646) {
-                log.info("[INS] {}", LogUtils.elapsedLog(tableName));
-            } else {
-                log.warn("[WAN] LinkTrafCenterService.run: {}: merge warning ({}).", tableName, insertCount);
-            }
-
-            // 3. DELETE 수행
-            int deleteCount = mapper.deleteTrafficCenterByDate(ApplicationRepository.trafPrcsTime.getPrcsTime());
-            if (deleteCount == -2147482646) {
-                log.info("[DEL] {}", LogUtils.elapsedLog(tableName));
-            } else {
-                log.warn("[WAN] LinkTrafCenterService.run: {}: delete warning ({}).", tableName, deleteCount);
-            }
-
-            // 4. 트랜잭션 커밋
-            sqlSession.commit();    // 작업 데이터가 여기서 반영됨
-
-            // 6. 세션 종료
-            sqlSession.close();
-        }
-        catch (Exception e) {
-            log.error("[ERR] LinkTrafCenterService.processing: Merge Method Error : {}", e.getMessage());
-            return false;
-        }
-        return true;
-    }
-
-    @ProcessingElapsed(type="TRAFFIC", name="교통정보 CENTER 저장", starting = false)
-    @Override
-    public boolean processing() {
-        final String tableName = ApplicationRepository.TABLE_TRAFFIC_CENTER;
-        try {
-            // 1. 세션 열기 (BATCH 모드 + 수동 커밋)
-            SqlSession sqlSession = this.sqlSessionFactory.openSession(ExecutorType.BATCH, false);
-            UticTrafficMapper mapper = sqlSession.getMapper(UticTrafficMapper.class);
-
-            // 2. 병렬 DML 세션 활성화
-            mapper.enableParallelDml(); // ALTER SESSION ENABLE PARALLEL DML
-
-            // 3. 병렬 DELETE 수행
-            int deleteCount = mapper.deleteTrafficCenter();
-            if (deleteCount == -2147482646) {
-                log.info("[DEL] {}: PARALLEL.", LogUtils.elapsedLog(tableName));
-            } else {
-                log.warn("[WAN] LinkTrafCenterService.run: {}: parallel delete warning ({}).", tableName, deleteCount);
-            }
-
-            // 4. 병렬 INSERT 수행
-            int insertCount = mapper.insertTrafficCenter();
-            if (insertCount == -2147482646) {
-                log.info("[INS] {}: PARALLEL.", LogUtils.elapsedLog(tableName));
-            } else {
-                log.warn("[WAN] LinkTrafCenterService.run: {}: parallel insert warning ({}).", tableName, insertCount);
-            }
-
-            // 5. 트랜잭션 커밋
-            sqlSession.commit();    // 작업 데이터가 여기서 반영됨
-            // 6. 세션 종료
-            sqlSession.close();
-        }
-        catch (Exception e) {
-            log.error("[ERR] LinkTrafCenterService.processing: Parallel Method Error : {}", e.getMessage());
-            return false;
-        }
-        return true;
-    }
-
-}

+ 11 - 137
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveDwdbService.java

@@ -6,10 +6,9 @@ import com.utic.center.common.spring.SpringUtils;
 import com.utic.center.common.utils.LogUtils;
 import com.utic.center.utic.traf.server.config.TraceConfig;
 import com.utic.center.utic.traf.server.dao.mapper.dwdb.DwdbTrafficMapper;
-import com.utic.center.utic.traf.server.dao.mapper.utic.UticTrafficMapper;
-import com.utic.center.utic.traf.server.dao.repository.dwdb.DwdbTrafficRepository;
-import com.utic.center.utic.traf.server.dao.repository.utic.UticTrafficRepository;
-import com.utic.center.utic.traf.server.dto.*;
+import com.utic.center.utic.traf.server.dto.DbmsBatchJobResult;
+import com.utic.center.utic.traf.server.dto.LinkDto;
+import com.utic.center.utic.traf.server.dto.LinkTrafCenterDto;
 import com.utic.center.utic.traf.server.repository.ApplicationRepository;
 import com.utic.center.utic.traf.server.service.worker.WorkerUtils;
 import lombok.Data;
@@ -22,14 +21,11 @@ import org.apache.ibatis.session.SqlSessionFactory;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
-import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 @Slf4j
 @Data
@@ -40,13 +36,9 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
 
     private final TraceConfig trace;
     private final LinkService linkService;
-    private final LinkTrafSaveCenterService linkTrafSaveCenterService;
-    private final UticTrafficRepository uticRepo;
-    private final DwdbTrafficRepository dwdbRepo;
-    private final UticTrafficMapper uticMapper;
-    private final DwdbTrafficMapper dwdbMapper;
 
     private SqlSessionFactory sqlSessionFactory;
+    private String histMonth;
 
     @PostConstruct
     public void init() {
@@ -54,12 +46,6 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
         this.sqlSessionFactory = (SqlSessionFactory) SpringUtils.getBean("dwdbSqlSessionFactory");
     }
 
-    private void insertLinkFusionLog() {
-        LinkTrafFusionInfo fusionInfo = this.linkService.getFusionInfo();
-        this.dwdbRepo.insertLinkFusionLog(fusionInfo);
-    }
-
-
     private void batchTrafficCenterHist(SqlSessionFactory sqlSessionFactory, DbmsBatchJobResult dbmsJobResult, LinkService linkRepo, String jobTable) {
         final long start = System.currentTimeMillis();
         final String mapperName = "insertTrafficCenterHist";
@@ -90,7 +76,7 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
 
                 LinkTrafCenterDto trafDto = link.getTrafCenter();
                 try {
-                    mapper.insertTrafficCenterHist(trafDto);
+                    mapper.insertTrafficCenterHist(this.histMonth, trafDto);
                     linkCounts[trafDto.getLinkLevel()-1]++;
                     jobCnt++;
 
@@ -124,7 +110,7 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
 
     private void insertTrafficCenterHist() {
         final long start = System.currentTimeMillis();
-        final String jobTable = ApplicationRepository.TABLE_TRAFFIC_CENTER_HIST;
+        final String jobTable = ApplicationRepository.TABLE_TRAFFIC_CENTER_HIST + this.histMonth + "@DWDB";
 
         // 모든 링크 레벨에 대하여 작업처리
         // this.linkService.getLinkLists()
@@ -137,6 +123,10 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
         final ConcurrentHashMap<Integer, DbmsBatchJobResult> mapData = new ConcurrentHashMap<>();
         final int prcsThreadCount = ApplicationRepository.PRCS_THREAD_COUNT;
         final int threadPoolSize = WorkerUtils.allocateWorkerLinkJobs(mapData, prcsThreadCount, this.linkService.getValidTrafLinkList());
+        if (threadPoolSize < 0) {
+            log.warn("[WAN] insertTrafficCenterHist: getValidTrafLinkList no data, job return: [{}].", jobTable);
+            return;
+        }
         final ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
 
         mapData.forEach((key, dbmsJobResult) -> {
@@ -175,128 +165,12 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
         log.info("[INF] {}", LogUtils.elapsedLog(jobTable, resultCount, System.currentTimeMillis() - start));
     }
 
-    private void batchLinkMissingValueHist(SqlSessionFactory sqlSessionFactory, DbmsBatchJobResult dbmsJobResult, LinkService linkService, String jobTable) {
-        final long start = System.currentTimeMillis();
-        final String mapperName = "insertLinkMissingValueHist";
-        final int maxBatchSize = ApplicationRepository.DBMS_BATCH_SIZE;
-        int total = 0;
-        int jobCnt = 0;
-
-        String exeDate = ApplicationRepository.trafPrcsTime.getPrcsTime().substring(0, 12);
-        try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
-            DwdbTrafficMapper mapper = sqlSession.getMapper(DwdbTrafficMapper.class);
-            for (String linkId : dbmsJobResult.getLinkIds()) {
-                LinkDto link = linkService.getLinkMap().get(linkId);
-                if (link == null) {
-                    log.error("[ERR] LinkTrafSaveDwdbService.batchLinkMissingValueHist: {} link not found.", linkId);
-                    continue;
-                }
-                LinkMissingValueHistDto valueHist = linkService.getMissingValueHist(link, exeDate);
-                if (valueHist == null) {
-                    continue;
-                }
-                total++;
-
-                try {
-                    mapper.insertLinkMissingValueHist(valueHist);
-                    jobCnt++;
-
-                    if (jobCnt % maxBatchSize == 0) {
-                        sqlSession.flushStatements();
-                    }
-                } catch (Exception e) {
-                    log.error("[ERR] batchLinkMissingValueHist({}): jobCnt({}), Exception, [{}], {}.",
-                            dbmsJobResult.getJobIndex(), jobCnt, valueHist, e.getMessage());
-                    break;
-                }
-            }
-            sqlSession.flushStatements();
-            sqlSession.commit();
-        } catch (Exception e) {
-            log.error("[ERR] batchLinkMissingValueHist({}): Exception, [{}], {}.", dbmsJobResult.getJobIndex(), jobTable, e.getMessage());
-        }
-
-        dbmsJobResult.setTotal(total);
-        dbmsJobResult.setTarget(total);
-        dbmsJobResult.setLink1(jobCnt);
-        dbmsJobResult.setLink2(0);
-        dbmsJobResult.setLink3(0);
-        dbmsJobResult.setLink4(0);
-        dbmsJobResult.setEffects(jobCnt);
-        dbmsJobResult.setElapsedTime(System.currentTimeMillis() - start);
-        if (this.trace.isDebug()) {
-            log.info("[INS] {} | {}", LogUtils.elapsedLog(mapperName + dbmsJobResult.getJobIndex(), jobCnt, dbmsJobResult.getElapsedTime()), Thread.currentThread().getName());
-        }
-    }
-
-    private void insertLinkMissingValueHist() {
-        final long start = System.currentTimeMillis();
-        final String jobTable = ApplicationRepository.TABLE_LINK_MISSING_VALUE_HIST;
-
-        // 레벨1 링크에 대해서만, 스레드는 4개로 고정
-        // this.linkService.getLink1Lists()
-//        final List<String> level1LinkList = this.linkService.getLinkMap().entrySet().stream()
-//                .filter(entry -> entry.getValue().getLinkLevel() == 1)
-//                .filter(entry -> entry.getValue().isPrcsPtrnMissing())
-//                .filter(entry -> entry.getValue().getTrafFsn().getState().getCrtDataType() != LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL)
-//                .filter(entry -> !"O".equals(entry.getValue().getTrafFsn().getState().getMissValueYn()))
-//                .map(Map.Entry::getKey)
-//                .collect(Collectors.toList());
-//        final List<String> level1LinkList = this.linkService.getLink1Lists().stream()
-//                .map(this.linkService.getLinkMap()::get)
-//                .filter(Objects::nonNull)
-//                .filter(LinkDto::isPrcsPtrnMissing)
-//                .filter(dto -> dto.getTrafFsn().getState().getCrtDataType() != LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL)
-//                .filter(dto -> !"O".equals(dto.getTrafFsn().getState().getMissValueYn()))
-//                .map(LinkDto::getLinkId)
-//                .collect(Collectors.toList());
-        final List<String> level1LinkList = this.linkService.getLink1Lists().parallelStream()
-                .map(this.linkService.getLinkMap()::get)
-                .filter(Objects::nonNull)
-                .filter(LinkDto::isPrcsPtrnMissing)
-                .filter(dto -> dto.getTrafFsn().getState().getCrtDataType() != LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL)
-                .filter(dto -> !"O".equals(dto.getTrafFsn().getState().getMissValueYn()))
-                .map(LinkDto::getLinkId)
-                .collect(Collectors.toList());
-
-        final ConcurrentHashMap<Integer, DbmsBatchJobResult> mapData = new ConcurrentHashMap<>();
-        final int prcsThreadCount = 4;
-        final int threadPoolSize = WorkerUtils.allocateWorkerLinkJobs(mapData, prcsThreadCount, level1LinkList);
-        final ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
-
-        mapData.forEach((key, dbmsJobResult) -> {
-            executorService.execute(() -> batchLinkMissingValueHist(this.sqlSessionFactory, dbmsJobResult, this.linkService, jobTable));
-        });
-
-        try {
-            executorService.shutdown();
-            if (!executorService.awaitTermination(100, TimeUnit.SECONDS)) {
-                log.warn("[WAN] insertLinkMissingValueHist: Timeout while waiting for tasks to finish, [{}].", jobTable);
-                executorService.shutdownNow();
-            }
-        } catch (InterruptedException e) {
-            log.error("[ERR] insertLinkMissingValueHist: InterruptedException, [{}], {}.", jobTable, e.getMessage());
-            executorService.shutdownNow();
-        }
-
-        int resultCount = 0;
-        long elapsedTime = 0;
-        for (Map.Entry<Integer, DbmsBatchJobResult> entry : mapData.entrySet()) {
-            DbmsBatchJobResult result = entry.getValue();
-            elapsedTime = Math.max(elapsedTime, result.getElapsedTime());
-            resultCount += result.getLink1();
-        }
-
-        log.info("[INF] {}", LogUtils.elapsedLog(jobTable, resultCount, System.currentTimeMillis() - start));
-    }
-
     @ProcessingElapsed(type="DWDB", name="교통정보 DWDB 저장", starting = false)
     @Override
     public boolean processing() {
+        this.histMonth = ApplicationRepository.trafPrcsTime.getPrcsTime().substring(4, 6);
 
-        insertLinkFusionLog();
         insertTrafficCenterHist();
-        insertLinkMissingValueHist();
 
         return true;
     }

+ 10 - 6
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveCacheService.java → utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveUticService.java

@@ -7,7 +7,7 @@ import com.utic.center.utic.traf.server.config.TraceConfig;
 import com.utic.center.utic.traf.server.dao.repository.utic.UticTrafficRepository;
 import com.utic.center.utic.traf.server.dto.DbmsJobResult;
 import com.utic.center.utic.traf.server.repository.ApplicationRepository;
-import com.utic.center.utic.traf.server.service.worker.LinkTrafSaveCacheWorker;
+import com.utic.center.utic.traf.server.service.worker.LinkTrafSaveUticWorker;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
@@ -23,18 +23,19 @@ import java.util.concurrent.TimeUnit;
 @ToString
 @RequiredArgsConstructor
 @Service
-public class LinkTrafSaveCacheService implements AbstractProcessService {
+public class LinkTrafSaveUticService implements AbstractProcessService {
 
     private final TraceConfig trace;
     private final LinkService linkService;
     private final UticTrafficRepository uticRepo;
 
     private final DbmsJobResult jobResult = DbmsJobResult.builder()
-            .tableName(ApplicationRepository.TABLE_TRAFFIC_CENTER_CACHE)
+            .tableName(ApplicationRepository.TABLE_TRAFFIC_CENTER)
             .effects(0).elapsedTime(0).build();
 
     private void initialize() {
-//        final long start = System.currentTimeMillis();
+
+        this.jobResult.setTableName(ApplicationRepository.nextTrafficCenter);//        final long start = System.currentTimeMillis();
         this.jobResult.setEffects(0);
         this.jobResult.setElapsedTime(0);
 
@@ -56,7 +57,7 @@ public class LinkTrafSaveCacheService implements AbstractProcessService {
     @Override
     public boolean processing() {
         final long start = System.currentTimeMillis();
-        final String jobTable = ApplicationRepository.TABLE_TRAFFIC_CENTER_CACHE;
+        final String jobTable = ApplicationRepository.nextTrafficCenter;
         final int THREAD_POOL_SIZE = 1;     // 작업 스레드 개수 설정
         final int TIMEOUT_SECONDS = 120;    // 최대 대기 시간 설정
 
@@ -67,7 +68,7 @@ public class LinkTrafSaveCacheService implements AbstractProcessService {
 //        this.uticRepo.truncateTrafficCenterCache();
 
         ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
-        executorService.execute(new LinkTrafSaveCacheWorker(this.linkService, this.jobResult, this.trace.isDebug()));
+        executorService.execute(new LinkTrafSaveUticWorker(ApplicationRepository.nextTrafficCenter, this.linkService, this.jobResult, this.trace.isDebug()));
 
         try {
             executorService.shutdown();
@@ -79,6 +80,9 @@ public class LinkTrafSaveCacheService implements AbstractProcessService {
             executorService.shutdownNow();
         }
 
+        // VIEW 의 source table을 변경한다.
+        this.uticRepo.swapTrafficCenterView(ApplicationRepository.nextTrafficCenter);
+
         // 모든 작업이 완료된 후 결과를 출력
         log.info("[INF] {}", LogUtils.elapsedLog(jobTable, this.jobResult.getEffects(), System.currentTimeMillis() - start));
         return true;

+ 12 - 7
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/worker/LinkTrafSaveCacheWorker.java → utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/worker/LinkTrafSaveUticWorker.java

@@ -23,8 +23,9 @@ import java.util.concurrent.TimeUnit;
 
 @Slf4j
 @RequiredArgsConstructor
-public class LinkTrafSaveCacheWorker implements Runnable {
+public class LinkTrafSaveUticWorker implements Runnable {
 
+    private final String tableName;
     private final LinkService linkService;
     private final DbmsJobResult dbmsJobResult;
     private final boolean isDebug;
@@ -37,7 +38,7 @@ public class LinkTrafSaveCacheWorker implements Runnable {
         ConcurrentHashMap<Integer, DbmsBatchJobResult> mapData = new ConcurrentHashMap<>();
         SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) SpringUtils.getBean("sqlSessionFactory");
         if (sqlSessionFactory == null) {
-            log.error("[ERR] LinkTrafSaveCenterWorker.run: SqlSessionFactory is null, [{}].", jobTable);
+            log.error("[ERR] LinkTrafSaveUticWorker.run: SqlSessionFactory is null, [{}].", jobTable);
             return;
         }
 
@@ -50,6 +51,10 @@ public class LinkTrafSaveCacheWorker implements Runnable {
 
         final int prcsThreadCount = ApplicationRepository.PRCS_THREAD_COUNT;
         final int threadPoolSize = WorkerUtils.allocateWorkerLinkJobs(mapData, prcsThreadCount, this.linkService.getValidTrafLinkList());
+        if (threadPoolSize < 0) {
+            log.warn("[WAN] LinkTrafSaveUticWorker.run: getValidTrafLinkList no data, job return: [{}].", jobTable);
+            return;
+        }
         final ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
 
         mapData.forEach((key, dbmsJobResult) -> {
@@ -59,11 +64,11 @@ public class LinkTrafSaveCacheWorker implements Runnable {
         try {
             executorService.shutdown();
             if (!executorService.awaitTermination(100, TimeUnit.SECONDS)) {
-                log.warn("[WAN] LinkTrafSaveCenterWorker.run: Timeout while waiting for tasks to finish, [{}].", jobTable);
+                log.warn("[WAN] LinkTrafSaveUticWorker.run: Timeout while waiting for tasks to finish, [{}].", jobTable);
                 executorService.shutdownNow();
             }
         } catch (InterruptedException e) {
-            log.error("[ERR] LinkTrafSaveCenterWorker.run: InterruptedException, [{}], {}.", jobTable, e.getMessage());
+            log.error("[ERR] LinkTrafSaveUticWorker.run: InterruptedException, [{}], {}.", jobTable, e.getMessage());
             executorService.shutdownNow();
         }
 
@@ -118,7 +123,7 @@ public class LinkTrafSaveCacheWorker implements Runnable {
 
                 LinkTrafCenterDto trafDto = link.getTrafCenter();
                 try {
-                    mapper.insertTrafficCenterCache(trafDto);
+                    mapper.insertTrafficCenter(this.tableName, trafDto);
                     linkCounts[trafDto.getLinkLevel()-1]++;
                     jobCnt++;
 
@@ -126,7 +131,7 @@ public class LinkTrafSaveCacheWorker implements Runnable {
                         sqlSession.flushStatements();
                     }
                 } catch (Exception e) {
-                    log.error("[ERR] LinkTrafSaveCenterWorker.processBatch({}): jobCnt({}), Exception, [{}], {}.",
+                    log.error("[ERR] LinkTrafSaveUticWorker.processBatch({}): jobCnt({}), Exception, [{}], {}.",
                             dbmsJobResult.getJobIndex(), jobCnt, trafDto, e.getMessage());
                     break;
                 }
@@ -134,7 +139,7 @@ public class LinkTrafSaveCacheWorker implements Runnable {
             sqlSession.flushStatements();
             sqlSession.commit();
         } catch (Exception e) {
-            log.error("[ERR] LinkTrafSaveCenterWorker.processBatch({}): Exception, [{}], {}.", dbmsJobResult.getJobIndex(), jobTable, e.getMessage());
+            log.error("[ERR] LinkTrafSaveUticWorker.processBatch({}): Exception, [{}], {}.", dbmsJobResult.getJobIndex(), jobTable, e.getMessage());
         }
 
         dbmsJobResult.setTotal(total);

+ 3 - 0
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/worker/WorkerUtils.java

@@ -16,6 +16,9 @@ public final class WorkerUtils {
     public static int allocateWorkerLinkJobs(ConcurrentHashMap<Integer, DbmsBatchJobResult> mapData, int configuredThreads, List<String> orgLinkLists) {
         // 몫+나머지를 앞쪽에 고르게 분산
         List<String> linkList = Optional.ofNullable(orgLinkLists).orElse(Collections.emptyList());
+        if (linkList.isEmpty()) {
+            return -1;  // FOR / by zero error
+        }
 
         int linkTotalCount = linkList.size();
         int threadPoolSize = Math.min(linkTotalCount, configuredThreads);   // 스레드 풀 크기 설정, 그럴일은 없겠지만,,, 링크 개수보다 작거나 같게 설정

+ 15 - 106
utic-traf-server/src/main/resources/mybatis/mapper/dwdb/DwdbTrafficMapper.xml

@@ -3,9 +3,22 @@
 
 <mapper namespace="com.utic.center.utic.traf.server.dao.mapper.dwdb.DwdbTrafficMapper">
 
-    <insert id="insertTrafficCenterHist" parameterType="com.utic.center.utic.traf.server.dto.LinkTrafCenterDto">
+    <select id="findTrafficCenterHistDataExists" parameterType="java.lang.String" resultType="com.utic.center.utic.traf.server.dto.DataCountDto">
+    <![CDATA[
+        SELECT CASE WHEN EXISTS (
+            SELECT 1 FROM TRAFFIC_CENTER_${targetMonth} WHERE ROWNUM = 1
+        ) THEN 1 ELSE 0 END AS dataCount
+        FROM DUAL
+        ]]>
+    </select>
+
+    <update id="truncateTrafficCenterHist" parameterType="java.lang.String">
+        TRUNCATE TABLE TRAFFIC_CENTER_${targetMonth}
+    </update>
+
+    <insert id="insertTrafficCenterHist">
         <![CDATA[
-        INSERT /*+ APPEND PARALLEL(TMP_TRAFFIC_CENTER_HIST, 2) */ INTO TMP_TRAFFIC_CENTER_HIST NOLOGGING (
+        INSERT /*+ APPEND PARALLEL(TRAFFIC_CENTER_${targetMonth}, 2) */ INTO TRAFFIC_CENTER_${targetMonth} NOLOGGING (
                         regdate        ,
                         linkid         ,
                         missvalueyn    ,
@@ -40,108 +53,4 @@
         ]]>
     </insert>
 
-    <insert id="insertLinkFusionLog" parameterType="com.utic.center.utic.traf.server.dto.LinkTrafFusionInfo">
-        <![CDATA[
-        INSERT INTO TMP_LINK_FUSION_LOG (
-            REGDATE,
-            PRCSTYPE,
-            LINKCNT,
-            COLOPR,
-            COLMOCT,
-            COLGPS,
-            COLUTIS,
-            COLPRI,
-            COLPRIETC,
-            COLDONGBU,
-            COLPNT,
-            FSNOPR,
-            FSNPRI,
-            FSNWGT,
-            MISSKNN,
-            MISSPSD,
-            MISSPTN,
-            MISSMOCT,
-            MISSGG,
-            KNN,
-            PSDUP,
-            PSDDN,
-            PSDUPDN,
-            PSDLV4,
-            FLTSPD,
-            ZEROSPD
-        )
-        VALUES(
-                  TO_DATE(#{obj.regDate}, 'YYYYMMDDHH24MISS'),
-                  #{obj.prcsType},
-                  #{obj.linkCnt},
-                  #{obj.colOprCnt},
-                  #{obj.colMoctCnt},
-                  #{obj.colGpsCnt},
-                  #{obj.colUtisCnt},
-                  #{obj.colPriCnt},
-                  #{obj.colPriEtcCnt},
-                  #{obj.colDongbuCnt},
-                  #{obj.colPtnCnt},
-                  #{obj.fsnOprCnt},
-                  #{obj.fsnPriCnt},
-                  #{obj.fsnWgtCnt},
-                  #{obj.missKnnCnt},
-                  #{obj.missPsdCnt},
-                  #{obj.missPtnCnt},
-                  #{obj.missMoctCnt},
-                  #{obj.missGgCnt},
-                  #{obj.knnCnt},
-                  #{obj.psdUpCnt},
-                  #{obj.psdDnCnt},
-                  #{obj.psdUpDnCnt},
-                  #{obj.psdLv4Cnt},
-                  #{obj.fltSpdCnt},
-                  #{obj.zeroSpdCnt}
-              )
-        ]]>
-    </insert>
-
-    <insert id="insertLinkMissingValueHist" parameterType="com.utic.center.utic.traf.server.dto.LinkMissingValueHistDto">
-        <![CDATA[
-        INSERT /*+ APPEND PARALLEL(TMP_LINK_MISSING_VALUE_HIST, 2) */ INTO TMP_LINK_MISSING_VALUE_HIST NOLOGGING (
-                    linkid          ,
-                    exe_date        ,
-                    l4_link_speed   ,
-                    up_link_speed   ,
-                    dn_link_speed   ,
-                    l4_patn_speed   ,
-                    up_patn_speed   ,
-                    dn_patn_speed   ,
-                    link_patn_speed ,
-                    missing_type    ,
-                    revision_speed  ,
-                    l4_linkid       ,
-                    up_linkid       ,
-                    dn_linkid       ,
-                    psdspeed        ,
-                    knnspeed        ,
-                    knncnt
-                    )
-        VALUES(
-            #{obj.linkId},
-            #{obj.exeDate},
-            DECODE(#{obj.l4LinkSpd},   0, NULL, #{obj.l4LinkSpd}),
-            DECODE(#{obj.upLinkSpd},   0, NULL, #{obj.upLinkSpd}),
-            DECODE(#{obj.dnLinkSpd},   0, NULL, #{obj.dnLinkSpd}),
-            DECODE(#{obj.l4PatnSpd},   0, NULL, #{obj.l4PatnSpd}),
-            DECODE(#{obj.upPatnSpd},   0, NULL, #{obj.upPatnSpd}),
-            DECODE(#{obj.dnPatnSpd},   0, NULL, #{obj.dnPatnSpd}),
-            DECODE(#{obj.linkPatnSpd}, 0, NULL, #{obj.linkPatnSpd}),
-            #{obj.missingType},
-            DECODE(#{obj.revisionSpd}, 0, NULL, #{obj.revisionSpd}),
-            #{obj.l4LinkId},
-            #{obj.upLinkId},
-            #{obj.dnLinkId},
-            DECODE(#{obj.psdSpeed},   0, NULL, #{obj.psdSpeed}),
-            DECODE(#{obj.knnSpeed},   0, NULL, #{obj.knnSpeed}),
-            DECODE(#{obj.knnCnt},     0, NULL, #{obj.knnCnt})
-            )
-        ]]>
-   </insert>
-
 </mapper>

+ 26 - 87
utic-traf-server/src/main/resources/mybatis/mapper/utic/UticTrafficMapper.xml

@@ -3,6 +3,28 @@
 
 <mapper namespace="com.utic.center.utic.traf.server.dao.mapper.utic.UticTrafficMapper">
 
+    <select id="findNextMonth" resultType="com.utic.center.utic.traf.server.dto.ViewTextDto">
+        <![CDATA[
+        SELECT TO_CHAR(ADD_MONTHS(SYSDATE, 1), 'MM') AS viewText FROM DUAL
+        ]]>
+    </select>
+
+    <select id="findTrafficCenterViewDdl" resultType="com.utic.center.utic.traf.server.dto.ViewTextDto">
+        <![CDATA[
+        SELECT TEXT AS viewText FROM USER_VIEWS WHERE VIEW_NAME = 'VW_TRAFFIC_CENTER'
+        ]]>
+    </select>
+<!--    <select id="findTrafficCenterViewDdl2" resultType="com.utic.center.utic.traf.server.dto.ViewTextDto">-->
+<!--        <![CDATA[-->
+<!--        SELECT DBMS_METADATA.GET_DDL('VIEW', 'VW_TRAFFIC_CENTER', 'UTIADMIN') AS viewText FROM DUAL-->
+<!--        ]]>-->
+<!--    </select>-->
+
+    <update id="swapTrafficCenterView">
+        CREATE OR REPLACE VIEW VW_TRAFFIC_CENTER AS
+        SELECT * FROM ${sourceTable}
+    </update>
+
     <select id="findOneTrafPrcsTime" resultType="com.utic.center.utic.traf.server.dto.TrafPrcsTimeDto">
         <![CDATA[
         SELECT TO_CHAR(SYSDATE,            'YYYYMMDDHH24MISS')     AS currTime,
@@ -28,15 +50,15 @@
         ]]>
     </insert>
 
-    <update id="truncateTrafficCenterCache">
+    <update id="truncateTrafficCenter">
         <![CDATA[
-        TRUNCATE TABLE TRAFFIC_CENTER_CACHE
+        TRUNCATE TABLE ${tableName}
         ]]>
     </update>
 
-    <insert id="insertTrafficCenterCache" parameterType="com.utic.center.utic.traf.server.dto.LinkTrafCenterDto">
+    <insert id="insertTrafficCenter">
         <![CDATA[
-        INSERT /*+ APPEND PARALLEL(TRAFFIC_CENTER_CACHE, 6) */ INTO TRAFFIC_CENTER_CACHE NOLOGGING (
+        INSERT /*+ APPEND PARALLEL(${tableName}, 6) */ INTO ${tableName} NOLOGGING (
             LINKID,
             MISSVALUEYN,
             REGDATE,
@@ -61,87 +83,4 @@
         ]]>
     </insert>
 
-    <update id="enableParallelDml">
-        ALTER SESSION ENABLE PARALLEL DML
-    </update>
-
-    <delete id="deleteTrafficCenter">
-        <![CDATA[
-        DELETE /*+ PARALLEL(TMP_TRAFFIC_CENTER, 8) */ FROM TMP_TRAFFIC_CENTER
-        ]]>
-    </delete>
-
-    <insert id="insertTrafficCenter">
-        <![CDATA[
-        INSERT /*+ APPEND PARALLEL(TMP_TRAFFIC_CENTER, 6) */ INTO TMP_TRAFFIC_CENTER NOLOGGING (
-            LINKID,
-            MISSVALUEYN,
-            REGDATE,
-            LINKLEVEL,
-            SPEED,
-            TRAVELTIME,
-            TRAFFICGRADE,
-            DATARESTYPE,
-            CENTERID
-            )
-        SELECT LINKID,
-               MISSVALUEYN,
-               REGDATE,
-               LINKLEVEL,
-               SPEED,
-               TRAVELTIME,
-               TRAFFICGRADE,
-               DATARESTYPE,
-               CENTERID
-        FROM TRAFFIC_CENTER_CACHE
-        ]]>
-    </insert>
-
-    <insert id="mergeTrafficCenter" parameterType="java.lang.String">
-        <![CDATA[
-        MERGE INTO TMP_TRAFFIC_CENTER T
-            USING TRAFFIC_CENTER_CACHE C
-            ON (T.LINKID = C.LINKID)
-            WHEN MATCHED THEN
-                UPDATE SET
-                    T.MISSVALUEYN  = C.MISSVALUEYN,
-                    T.REGDATE      = C.REGDATE,
-                    T.LINKLEVEL    = C.LINKLEVEL,
-                    T.SPEED        = C.SPEED,
-                    T.TRAVELTIME   = C.TRAVELTIME,
-                    T.TRAFFICGRADE = C.TRAFFICGRADE,
-                    T.DATARESTYPE  = C.DATARESTYPE,
-                    T.CENTERID     = C.CENTERID
-            WHEN NOT MATCHED THEN
-                INSERT (
-                        LINKID,
-                        MISSVALUEYN,
-                        REGDATE,
-                        LINKLEVEL,
-                        SPEED,
-                        TRAVELTIME,
-                        TRAFFICGRADE,
-                        DATARESTYPE,
-                        CENTERID
-                    )
-                    VALUES (
-                               C.LINKID,
-                               C.MISSVALUEYN,
-                               C.REGDATE,
-                               C.LINKLEVEL,
-                               C.SPEED,
-                               C.TRAVELTIME,
-                               C.TRAFFICGRADE,
-                               C.DATARESTYPE,
-                               C.CENTERID
-                           )
-        ]]>
-    </insert>
-
-    <delete id="deleteTrafficCenterByDate" parameterType="java.lang.String">
-        <![CDATA[
-        DELETE FROM TMP_TRAFFIC_CENTER T WHERE T.REGDATE < TO_DATE(#{prcsTime}, 'YYYYMMDDHH24MISS')
-        ]]>
-    </delete>
-
 </mapper>