HANTE 5 tháng trước cách đây
mục cha
commit
c719b4ea2f
30 tập tin đã thay đổi với 709 bổ sung283 xóa
  1. 5 0
      utic-ptis-server/src/main/java/com/utic/ptis/server/config/ApplicationConfig.java
  2. 23 25
      utic-ptis-server/src/main/java/com/utic/ptis/server/config/ThreadPoolInitializer.java
  3. 21 15
      utic-ptis-server/src/main/java/com/utic/ptis/server/controller/LinkTrafPrcsController.java
  4. 2 2
      utic-ptis-server/src/main/java/com/utic/ptis/server/controller/LinkTrafPrcsPrepareController.java
  5. 4 3
      utic-ptis-server/src/main/java/com/utic/ptis/server/dao/mapper/dwdb/DwdbTrafficMapper.java
  6. 24 0
      utic-ptis-server/src/main/java/com/utic/ptis/server/dto/DbmsBatchJobResult.java
  7. 1 1
      utic-ptis-server/src/main/java/com/utic/ptis/server/dto/DbmsJobResult.java
  8. 1 1
      utic-ptis-server/src/main/java/com/utic/ptis/server/dto/LinkDto.java
  9. 6 0
      utic-ptis-server/src/main/java/com/utic/ptis/server/dto/LinkTrafCenterDto.java
  10. 6 1
      utic-ptis-server/src/main/java/com/utic/ptis/server/dto/LinkTrafVal.java
  11. 1 1
      utic-ptis-server/src/main/java/com/utic/ptis/server/scheduler/LinkTrafPrcsScheduler.java
  12. 36 75
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkRepositoryService.java
  13. 1 1
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafCollectService.java
  14. 20 5
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafDeleteService.java
  15. 20 7
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafFusionService.java
  16. 22 9
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafMissingService.java
  17. 2 0
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafPatternService.java
  18. 1 1
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafPrcsTime.java
  19. 85 1
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafSaveService.java
  20. 2 2
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafDeleteWorker.java
  21. 52 0
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveCenterExtWorker.java
  22. 52 0
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveCenterWorker.java
  23. 147 0
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveDwdbCenterHistWorker.java
  24. 45 0
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveDwdbFusionLogWorker.java
  25. 50 0
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveDwdbMissingValueHistWorker.java
  26. 0 46
      utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveWorker.java
  27. 1 0
      utic-ptis-server/src/main/resources/application.yml
  28. 59 64
      utic-ptis-server/src/main/resources/mybatis/mapper/dwdb/DwdbTrafficMapper.xml
  29. 18 22
      utic-ptis-server/src/main/resources/mybatis/mapper/utic/UticTrafficMapper.xml
  30. 2 1
      utic-ptis-server/src/main/resources/mybatis/mybatis-config.xml

+ 5 - 0
utic-ptis-server/src/main/java/com/utic/ptis/server/config/ApplicationConfig.java

@@ -23,6 +23,7 @@ public class ApplicationConfig {
     private String processId = "70030";
     private int errTimeGap = 120;
     private int prcsThreadCount = 10;
+    private int dbmsBatchSize = 1000;
 
     private int dbmsWorkers = 0;
     private int queueSize = 0;
@@ -41,6 +42,10 @@ public class ApplicationConfig {
         if (this.queueSize == 0) {
             this.queueSize = 1000;
         }
+        if (this.dbmsBatchSize <= 1000) {
+            this.dbmsBatchSize = 1000;
+        }
+        this.dbmsBatchSize = Math.max(this.dbmsBatchSize, 2000);
 
         this.repo.processState.setProcessId(this.processId);
         this.repo.processState.setErrTimeGap(this.getErrTimeGap());

+ 23 - 25
utic-ptis-server/src/main/java/com/utic/ptis/server/config/ThreadPoolInitializer.java

@@ -4,14 +4,12 @@ import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
 import javax.annotation.PostConstruct;
-import java.util.concurrent.Executor;
 
 @Slf4j
 @Getter
@@ -50,27 +48,27 @@ public class ThreadPoolInitializer extends AsyncConfigurerSupport {
         return threadPoolTaskExecutor;
     }
 
-    @Bean(name="dbmsDataExecutor")
-    public Executor getDbmsDataExecutor() {
-        ThreadPoolTaskExecutor threadPoolTaskExecutor = getDefaultExecutor(this.dbms*2);
-        threadPoolTaskExecutor.setThreadNamePrefix("dbms-pool-");
-        threadPoolTaskExecutor.initialize();
-        return threadPoolTaskExecutor;
-    }
-
-    @Bean(name="workDataExecutor")
-    public Executor getWorkDataExecutor() {
-        ThreadPoolTaskExecutor threadPoolTaskExecutor = getDefaultExecutor(this.work*2);
-        threadPoolTaskExecutor.setThreadNamePrefix("work-pool-");
-        threadPoolTaskExecutor.initialize();
-        return threadPoolTaskExecutor;
-    }
-
-    @Bean(name="kafkaDataExecutor")
-    public Executor getKafkaDataExecutor() {
-        ThreadPoolTaskExecutor threadPoolTaskExecutor = getDefaultExecutor(this.kafka*2);
-        threadPoolTaskExecutor.setThreadNamePrefix("kafka-pool-");
-        threadPoolTaskExecutor.initialize();
-        return threadPoolTaskExecutor;
-    }
+//    @Bean(name="dbmsDataExecutor")
+//    public Executor getDbmsDataExecutor() {
+//        ThreadPoolTaskExecutor threadPoolTaskExecutor = getDefaultExecutor(this.dbms*2);
+//        threadPoolTaskExecutor.setThreadNamePrefix("dbms-pool-");
+//        threadPoolTaskExecutor.initialize();
+//        return threadPoolTaskExecutor;
+//    }
+//
+//    @Bean(name="workDataExecutor")
+//    public Executor getWorkDataExecutor() {
+//        ThreadPoolTaskExecutor threadPoolTaskExecutor = getDefaultExecutor(this.work*2);
+//        threadPoolTaskExecutor.setThreadNamePrefix("work-pool-");
+//        threadPoolTaskExecutor.initialize();
+//        return threadPoolTaskExecutor;
+//    }
+//
+//    @Bean(name="kafkaDataExecutor")
+//    public Executor getKafkaDataExecutor() {
+//        ThreadPoolTaskExecutor threadPoolTaskExecutor = getDefaultExecutor(this.kafka*2);
+//        threadPoolTaskExecutor.setThreadNamePrefix("kafka-pool-");
+//        threadPoolTaskExecutor.initialize();
+//        return threadPoolTaskExecutor;
+//    }
 }

+ 21 - 15
utic-ptis-server/src/main/java/com/utic/ptis/server/controller/LinkTrafPrcsController.java

@@ -13,7 +13,8 @@ import org.springframework.util.StopWatch;
 public class LinkTrafPrcsController implements AbstractProcessController {
 
     private final LinkTrafPrcsTime prcsTime;
-    private final LinkRepositoryService repositoryService;
+    private final LinkTrafParamService trafParamService;
+    private final LinkRepositoryService linkRepo;
     private final LinkTrafDeleteService trafDeleteService;
     private final LinkTrafCollectService trafCollectService;
     private final LinkTrafFusionService trafFusionService;
@@ -32,7 +33,7 @@ public class LinkTrafPrcsController implements AbstractProcessController {
         this.toTime = TimeUtils.getToTime(this.fromTime, TimeUtils.TYPE_PRCS_15MIN);
 
         String funcName = String.format("%45s", "LinkTrafPrcsController.initialize");
-        log.info("[SCHEDULING] {}: ..05M, {}, {}, {}, {}", funcName, currTime, this.statTime, this.fromTime, this.toTime);
+        log.info("[PRCS...] {}: ..05M, {}, {}, {}, {}", funcName, currTime, this.statTime, this.fromTime, this.toTime);
 
         /*
          * 가공에 사용되는 시각 정보를 초기화 한다.
@@ -40,16 +41,21 @@ public class LinkTrafPrcsController implements AbstractProcessController {
          */
         this.prcsTime.init();
 
-        this.repositoryService.getFusionInfo().init();
-
-        log.info("[PROCESSING]Current/Current_5M/Current_5M_Prcs: {}/{}/{}",    this.prcsTime.getCurrTime(),      this.prcsTime.getCurrFiveMin(),     this.prcsTime.getPrcsFiveMin());
-        log.info("[PROCESSING]         Current_5M_Prcs/Start/End: {}/{}/{}",    this.prcsTime.getPrcsFiveMin(),   this.prcsTime.getPrcsFiveMinFrom(), this.prcsTime.getPrcsFiveMinTo());
-        log.info("[PROCESSING]      Current_5M_Prcs/Week/Quarter: {}/{}/{}/{}", this.prcsTime.getPrcsFiveMin(),   this.prcsTime.getPrcsDayWeek(),     this.prcsTime.getPrcsDayQuater(),      this.prcsTime.getPrcsDayWeekCd());
-        log.info("[PROCESSING]          15M:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStat15MinTime(), this.prcsTime.getStat15MinFrom(),   this.prcsTime.getStat15MinTo(),        this.prcsTime.isStat15Min());
-        log.info("[PROCESSING]         Hour:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStatHourTime(),  this.prcsTime.getStatHourFrom(),    this.prcsTime.getStatHourTo(),         this.prcsTime.isStatHour());
-        log.info("[PROCESSING]          Day:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStatDayTime(),   this.prcsTime.getStatDayFrom(),     this.prcsTime.getStatDayTo(),          this.prcsTime.isStatDay());
-        log.info("[PROCESSING]        Month:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStatMonTime(),   this.prcsTime.getStatMonFrom(),     this.prcsTime.getStatMonTo(),          this.prcsTime.isStatMon());
-        log.info("[PROCESSING]         Year:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStatYearTime(),  this.prcsTime.getStatYearFrom(),    this.prcsTime.getStatYearTo(),         this.prcsTime.isStatYear());
+        this.linkRepo.setPrcsTime(this.prcsTime.getCurrFiveMin());
+
+        this.linkRepo.getFusionInfo().init();
+        this.linkRepo.getFusionInfo().setRegDate(this.prcsTime.getCurrFiveMin());
+        this.linkRepo.getFusionInfo().setPrcsType(this.trafParamService.getAnalysisType().getAnalysisType());
+        this.linkRepo.getFusionInfo().setLinkCnt(this.linkRepo.getLink1Count());
+
+        log.info("[TIME...]Current/Current_5M/Current_5M_Prcs: {}/{}/{}",    this.prcsTime.getCurrTime(),      this.prcsTime.getCurrFiveMin(),     this.prcsTime.getPrcsFiveMin());
+        log.info("[TIME...]         Current_5M_Prcs/Start/End: {}/{}/{}",    this.prcsTime.getPrcsFiveMin(),   this.prcsTime.getPrcsFiveMinFrom(), this.prcsTime.getPrcsFiveMinTo());
+        log.info("[TIME...]      Current_5M_Prcs/Week/Quarter: {}/{}/{}/{}", this.prcsTime.getPrcsFiveMin(),   this.prcsTime.getPrcsDayWeek(),     this.prcsTime.getPrcsDayQuater(),      this.prcsTime.getPrcsDayWeekCd());
+        log.info("[TIME...]          15M:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStat15MinTime(), this.prcsTime.getStat15MinFrom(),   this.prcsTime.getStat15MinTo(),        this.prcsTime.isStat15Min());
+        log.info("[TIME...]         Hour:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStatHourTime(),  this.prcsTime.getStatHourFrom(),    this.prcsTime.getStatHourTo(),         this.prcsTime.isStatHour());
+        log.info("[TIME...]          Day:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStatDayTime(),   this.prcsTime.getStatDayFrom(),     this.prcsTime.getStatDayTo(),          this.prcsTime.isStatDay());
+        log.info("[TIME...]        Month:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStatMonTime(),   this.prcsTime.getStatMonFrom(),     this.prcsTime.getStatMonTo(),          this.prcsTime.isStatMon());
+        log.info("[TIME...]         Year:PrcsTM/Start/End/Run: {}/{}/{}/{}", this.prcsTime.getStatYearTime(),  this.prcsTime.getStatYearFrom(),    this.prcsTime.getStatYearTo(),         this.prcsTime.isStatYear());
     }
 
     public void run() {
@@ -60,7 +66,7 @@ public class LinkTrafPrcsController implements AbstractProcessController {
 
         StopWatch stopWatch = new StopWatch();
         stopWatch.start("LinkTrafPrcsController");
-        log.info("[TRAFFIC---]                         LinkTrafPrcsController: START.");
+        log.info("[TRAFFIC]                         LinkTrafPrcsController: START.");
 
         // 가공 시작
         this.prcsTime.setProcessing(true);
@@ -85,9 +91,9 @@ public class LinkTrafPrcsController implements AbstractProcessController {
 
         // 5. 소통정보 저장
         this.trafSaveService.processing();
-
+        this.prcsTime.setProcessing(false);
         stopWatch.stop();
-        log.info("[TRAFFIC---]                         LinkTrafPrcsController: ..END. {} ms", stopWatch.getTotalTimeMillis());
+        log.info("[TRAFFIC]                         LinkTrafPrcsController: ..END. {} ms", stopWatch.getTotalTimeMillis());
 
     }
 }

+ 2 - 2
utic-ptis-server/src/main/java/com/utic/ptis/server/controller/LinkTrafPrcsPrepareController.java

@@ -23,7 +23,7 @@ public class LinkTrafPrcsPrepareController implements AbstractProcessController
     public void run() {
         StopWatch stopWatch = new StopWatch();
         stopWatch.start("LinkTrafPrcsPrepareController");
-        log.info("[PREPARE---]                  LinkTrafPrcsPrepareController: START.");
+        log.info("[PREPARE]                  LinkTrafPrcsPrepareController: START.");
 
         /*
          * 가공에 사용되는 시각 정보를 초기화 한다.
@@ -42,6 +42,6 @@ public class LinkTrafPrcsPrepareController implements AbstractProcessController
         this.linkTrafPatternService.processing();
 
         stopWatch.stop();
-        log.info("[PREPARE---]                  LinkTrafPrcsPrepareController: ..END. {} ms", stopWatch.getTotalTimeMillis());
+        log.info("[PREPARE]                  LinkTrafPrcsPrepareController: ..END. {} ms", stopWatch.getTotalTimeMillis());
     }
 }

+ 4 - 3
utic-ptis-server/src/main/java/com/utic/ptis/server/dao/mapper/dwdb/DwdbTrafficMapper.java

@@ -1,13 +1,14 @@
 package com.utic.ptis.server.dao.mapper.dwdb;
 
-import com.utic.ptis.server.dto.LinkTrafCenterHistDto;
+import com.utic.ptis.server.dto.LinkMissingValueHist;
+import com.utic.ptis.server.dto.LinkTrafCenterDto;
 import com.utic.ptis.server.dto.LinkTrafFusionInfo;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
 @Mapper
 public interface DwdbTrafficMapper {
-    int insertTrafficCenterHist(@Param("obj") LinkTrafCenterHistDto obj);
+    int insertTrafficCenterHist(@Param("obj") LinkTrafCenterDto obj);
     int insertLinkFusionLog(@Param("obj") LinkTrafFusionInfo obj);
-
+    int insertLinkMissingValueHist(@Param("obj") LinkMissingValueHist obj);
 }

+ 24 - 0
utic-ptis-server/src/main/java/com/utic/ptis/server/dto/DbmsBatchJobResult.java

@@ -0,0 +1,24 @@
+package com.utic.ptis.server.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor//(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
+public class DbmsBatchJobResult {
+    private int jobIndex;
+    private int start;
+    private int end;
+    private int total;
+    private int target;
+    private int effects;
+    private int link1;
+    private int link2;
+    private int link3;
+    private int link4;
+    private long elapsedTime;
+}

+ 1 - 1
utic-ptis-server/src/main/java/com/utic/ptis/server/dto/DbmsJobResultDto.java → utic-ptis-server/src/main/java/com/utic/ptis/server/dto/DbmsJobResult.java

@@ -9,7 +9,7 @@ import lombok.NoArgsConstructor;
 @Builder
 @NoArgsConstructor//(access = AccessLevel.PROTECTED)
 @AllArgsConstructor
-public class DbmsJobResultDto {
+public class DbmsJobResult {
     private String tableName;
     private int effects;
     private long elapsedTime;

+ 1 - 1
utic-ptis-server/src/main/java/com/utic/ptis/server/dto/LinkDto.java

@@ -38,7 +38,7 @@ public class LinkDto  implements Serializable {
     private LinkTrafMiss missKnn;       // k-NN 알고리즘 수행 값
 
     public LinkTrafCenterDto getTrafficDto(String regDate) {
-        return this.trafFsn.toDto(this.linkId, this.linkLevel, regDate);
+        return this.trafFsn.toDto(this.linkId, this.linkLevel, regDate, missPsd, missKnn, 0);
     }
 
     public void init() {

+ 6 - 0
utic-ptis-server/src/main/java/com/utic/ptis/server/dto/LinkTrafCenterDto.java

@@ -17,6 +17,12 @@ public class LinkTrafCenterDto {
     private int    speed;
     private int    travelTime;
     private String trafficGrade;
+    private String incidentId;
     private String dataResType;
     private String centerId;
+
+    private String psdMissValueYn;
+    private int    psdSpeed;
+    private int    knnSpeed;
+    private int    knnCnt;
 }

+ 6 - 1
utic-ptis-server/src/main/java/com/utic/ptis/server/dto/LinkTrafVal.java

@@ -35,7 +35,7 @@ public class LinkTrafVal implements Serializable {
         this.travelTime = val.getTravelTime();
     }
 
-    public LinkTrafCenterDto toDto(String linkId, int linkLevel, String regDate) {
+    public LinkTrafCenterDto toDto(String linkId, int linkLevel, String regDate, LinkTrafMiss missPsd, LinkTrafMiss missKnn, int knnCnt) {
         return LinkTrafCenterDto.builder()
                 .linkId(linkId)
                 .missValueYn(this.getState().getMissValueYn())
@@ -44,8 +44,13 @@ public class LinkTrafVal implements Serializable {
                 .speed(this.speed)
                 .travelTime(this.travelTime)
                 .trafficGrade("0" + this.getState().getTrafficGrade())
+                .incidentId("")
                 .dataResType(this.getState().getDataResType())
                 .centerId(this.centerId)
+                .psdMissValueYn(missPsd.getMissValueYn())
+                .psdSpeed(missPsd.getSpeed())
+                .knnSpeed(missKnn.getSpeed())
+                .knnCnt(knnCnt)
                 .build();
     }
 

+ 1 - 1
utic-ptis-server/src/main/java/com/utic/ptis/server/scheduler/LinkTrafPrcsScheduler.java

@@ -26,7 +26,7 @@ public class LinkTrafPrcsScheduler {
             job.run();
         }
         catch(Exception e) {
-            log.error("[SCHEDULE] LinkTrafPrcsSchedulerTask: schedule job run failed: {}, {}", jobName, e.getMessage());
+            log.error("[CRONJOB] LinkTrafPrcsScheduler: schedule job run failed: {}, {}", jobName, e.getMessage());
         }
     }
 

+ 36 - 75
utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkRepositoryService.java

@@ -9,6 +9,7 @@ import com.utic.ptis.server.dto.LinkDto;
 import com.utic.ptis.server.dto.LinkTrafFusionInfo;
 import com.utic.ptis.server.dto.LogicalLinkDto;
 import com.utic.ptis.server.repository.ApplicationRepository;
+import com.utic.ptis.server.utils.LogUtils;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -31,22 +32,21 @@ public class LinkRepositoryService implements AbstractProcessService {
     private final LinkTrafParamService linkTrafParamService;
 
     private final ConcurrentHashMap<String, LinkDto> linkMap = new ConcurrentHashMap<>();
-
-    private String[] link1Arr = null;
-    private String[] link2Arr = null;
-    private String[] link3Arr = null;
-    private String[] link4Arr = null;
-
-    private final ConcurrentHashMap<String, LinkDto> level1Map = new ConcurrentHashMap<>();
-    private final ConcurrentHashMap<String, LinkDto> level2Map = new ConcurrentHashMap<>();
-    private final ConcurrentHashMap<String, LinkDto> level3Map = new ConcurrentHashMap<>();
-    private final ConcurrentHashMap<String, LinkDto> level4Map = new ConcurrentHashMap<>();
-
     private final LinkTrafFusionInfo fusionInfo = new LinkTrafFusionInfo();
+    private volatile String[] linkArr = null;
+    private volatile String[] link1Arr = null;
+    private int link1Count = 0;
+    private int link2Count = 0;
+    private int link3Count = 0;
+    private int link4Count = 0;
+    private String prcsTime;
 
     public LinkDto getLink(String linkId) {
         return this.linkMap.get(linkId);
     }
+    public void setPrcsTime(String prcsTime) {
+        this.prcsTime = prcsTime;
+    }
 
     private boolean initializeLinkCount() {
         boolean result = true;
@@ -56,32 +56,24 @@ public class LinkRepositoryService implements AbstractProcessService {
         log.info("[INIT...] findLinkCount: LV1({}), LV2({}), LV3({}), LV4({}). {}",
                 linkCount.getLevel1(), linkCount.getLevel2(), linkCount.getLevel3(), linkCount.getLevel4(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
 
-        if (linkCount.getLevel1() > 0) {
-            this.link1Arr = new String[linkCount.getLevel1()];
-        }
-        else {
-            log.error("[INIT...] linkCount.getLevel1() is zero.");
-            result = false;
-        }
-        if (linkCount.getLevel2() > 0) {
-            this.link2Arr = new String[linkCount.getLevel2()];
+        this.link1Count = linkCount.getLevel1();
+        this.link2Count = linkCount.getLevel2();
+        this.link3Count = linkCount.getLevel3();
+        this.link4Count = linkCount.getLevel4();
+
+        int totalLinkCount = this.link1Count + this.link2Count + this.link3Count + this.link4Count;
+        if (this.link1Count > 0) {
+            this.link1Arr = new String[this.link1Count];
         }
         else {
-            log.error("[INIT...] linkCount.getLevel2() is zero.");
+            log.error("[INIT...] totalLinkCount is zero.");
             result = false;
         }
-        if (linkCount.getLevel3() > 0) {
-            this.link3Arr = new String[linkCount.getLevel3()];
-            result = false;
+        if (totalLinkCount > 0) {
+            this.linkArr = new String[totalLinkCount];
         }
         else {
-            log.error("[INIT...] linkCount.getLevel3() is zero.");
-        }
-        if (linkCount.getLevel4() > 0) {
-            this.link4Arr = new String[linkCount.getLevel4()];
-        }
-        else {
-            log.error("[INIT...] linkCount.getLevel4() is zero.");
+            log.error("[INIT...] totalLinkCount is zero.");
             result = false;
         }
         log.info("[INIT...] findLinkCount. {}", Elapsed.elapsedStr(elapsed.nanoSeconds()));
@@ -93,62 +85,31 @@ public class LinkRepositoryService implements AbstractProcessService {
         log.info("[INIT...] findLinkAll.");
         Elapsed elapsed = new Elapsed();
         List<LinkDto> links = this.linkMapper.findLinkAll();
-        log.info("[INIT...] findLinkAll: {} EA. {}", links.size(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
+        log.info("[INIT...] findLinkAll:  (SEL) {}", LogUtils.elapsedLog("LINK", links.size(), elapsed.milliSeconds()));
+
         Elapsed tmpElapsed = new Elapsed();
         int link1, link2, link3, link4;
+        int linkCnt = 0;
         link1 = link2 = link3 = link4 = 0;
         for (LinkDto link : links) {
             link.init();
 
-            boolean loading = true;
             if (link.getLinkLevel() == 1) {
-                if (link1 < this.link1Arr.length) {
-                    this.link1Arr[link1++] = link.getLinkId();
-                    this.level1Map.put(link.getLinkId(), link);
-                }
-                else {
-                    log.error("[INIT...] link1Arr is full. {} / {}", link1, this.link1Arr.length);
-                    loading = false;
-                }
+                this.link1Arr[link1++] = link.getLinkId();
             } else if (link.getLinkLevel() == 2) {
-                if (link2 < this.link2Arr.length) {
-                    this.link2Arr[link2++] = link.getLinkId();
-                    this.level2Map.put(link.getLinkId(), link);
-                }
-                else {
-                    log.error("[INIT...] link2Arr is full. {} / {}", link2, this.link2Arr.length);
-                    loading = false;
-                }
+                link2++;
             } else if (link.getLinkLevel() == 3) {
-                if (link3 < this.link3Arr.length) {
-                    this.link3Arr[link3++] = link.getLinkId();
-                    this.level3Map.put(link.getLinkId(), link);
-                }
-                else {
-                    log.error("[INIT...] link3Arr is full. {} / {}", link3, this.link3Arr.length);
-                    loading = false;
-                }
+                link3++;
             } else if (link.getLinkLevel() == 4) {
-                if (link4 < this.link4Arr.length) {
-                    this.link4Arr[link4++] = link.getLinkId();
-                    this.level4Map.put(link.getLinkId(), link);
-                }
-                else {
-                    log.error("[INIT...] link4Arr is full. {} / {}", link4, this.link4Arr.length);
-                    loading = false;
-                }
-            }
-            if (loading) {
-                // 배열에 정상적으로 저장되었을 경우에만 맵에 저장한다.
-                this.linkMap.put(link.getLinkId(), link);
-            }
-            else {
-                result = loading;
+                link4++;
             }
+            this.linkArr[linkCnt++] = link.getLinkId();
+            this.linkMap.put(link.getLinkId(), link);
         }
-        log.info("[INIT...] findLinkAll: Arr, LV1({}), LV2({}), LV3({}), LV4({}).", link1, link2, link3, link4);
-        log.info("[INIT...] findLinkAll: Map, LV1({}), LV2({}), LV3({}), LV4({}). {} EA. {}",
-                level1Map.size(), level2Map.size(), level3Map.size(), level4Map.size(), linkMap.size(), Elapsed.elapsedStr(tmpElapsed.nanoSeconds()));
+        log.info("[INIT...] findLinkAll:  (MEM) {}, LV1({}), LV2({}), LV3({}), LV4({}).",
+                LogUtils.elapsedLog("MemoryAllocate", linkCnt, tmpElapsed.milliSeconds()),
+                link1, link2, link3, link4);
+
         log.info("[INIT...] findLinkAll. {}", Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return result;
     }

+ 1 - 1
utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafCollectService.java

@@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
 public class LinkTrafCollectService implements AbstractProcessService {
 
     private final LinkTrafPrcsTime prcsTime;
-    private final LinkRepositoryService linkRepositoryService;
+    private final LinkRepositoryService linkRepo;
     private final LinkTrafCollectSetupService collectSetupService;
 
     private ConcurrentHashMap<String, LinkCollectResultDto> mapData = new ConcurrentHashMap<>();

+ 20 - 5
utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafDeleteService.java

@@ -2,8 +2,9 @@ package com.utic.ptis.server.service;
 
 import com.utic.common.utils.Elapsed;
 import com.utic.ptis.server.dao.mapper.utic.UticTrafficMapper;
-import com.utic.ptis.server.dto.DbmsJobResultDto;
+import com.utic.ptis.server.dto.DbmsJobResult;
 import com.utic.ptis.server.service.worker.LinkTrafDeleteWorker;
+import com.utic.ptis.server.utils.LogUtils;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
@@ -11,6 +12,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -27,7 +29,7 @@ public class LinkTrafDeleteService implements AbstractProcessService {
     public static final String TABLE_TRAFFIC_CENTER_EXT = "TRAFFIC_CENTER_EXT";
 
     private ExecutorService executorService = Executors.newFixedThreadPool(2);
-    private ConcurrentHashMap<String, DbmsJobResultDto> mapData = new ConcurrentHashMap<>();
+    private ConcurrentHashMap<String, DbmsJobResult> mapData = new ConcurrentHashMap<>();
     private final UticTrafficMapper mapper;
 
     @PostConstruct
@@ -36,8 +38,8 @@ public class LinkTrafDeleteService implements AbstractProcessService {
         Elapsed elapsed = new Elapsed();
 
         // 초기화
-        this.mapData.put(TABLE_TRAFFIC_CENTER, DbmsJobResultDto.builder().tableName(TABLE_TRAFFIC_CENTER).effects(0).elapsedTime(0).build());
-        this.mapData.put(TABLE_TRAFFIC_CENTER_EXT, DbmsJobResultDto.builder().tableName(TABLE_TRAFFIC_CENTER_EXT).effects(0).elapsedTime(0).build());
+        this.mapData.put(TABLE_TRAFFIC_CENTER, DbmsJobResult.builder().tableName(TABLE_TRAFFIC_CENTER).effects(0).elapsedTime(0).build());
+        this.mapData.put(TABLE_TRAFFIC_CENTER_EXT, DbmsJobResult.builder().tableName(TABLE_TRAFFIC_CENTER_EXT).effects(0).elapsedTime(0).build());
 
         log.info("[DELETE.] LinkTrafDeleteService.init: end. {} ms.", elapsed.milliSeconds());
     }
@@ -46,12 +48,15 @@ public class LinkTrafDeleteService implements AbstractProcessService {
         log.info("[DELETE.] LinkTrafDeleteService.processing: start.");
         Elapsed elapsed = new Elapsed();
 
+        if (this.executorService.isShutdown() || this.executorService.isTerminated()) {
+            this.executorService = Executors.newFixedThreadPool(2);
+        }
+
         this.mapData.forEach((deleteTable, result) -> {
             result.setEffects(0);
             result.setElapsedTime(0);
             this.executorService.execute(new LinkTrafDeleteWorker(deleteTable, result, this.mapper));
         });
-
         log.info("[DELETE.] LinkTrafDeleteService.processing: end. {}", Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return 2;
     }
@@ -66,6 +71,16 @@ public class LinkTrafDeleteService implements AbstractProcessService {
             log.error("[DELETE.] LinkTrafDeleteService.waitForComplete: LinkTrafDeleteWorker InterruptedException, {}", e.getMessage());
             executorService.shutdownNow();
         }
+
+        // 모든 작업이 완료된 후 결과를 출력
+        long elapsedTime = 0;
+        for (Map.Entry<String, DbmsJobResult> entry : this.mapData.entrySet()) {
+            DbmsJobResult result = entry.getValue();
+            elapsedTime = Math.max(elapsedTime, result.getElapsedTime());
+            log.info("[DELETE.] LinkTrafDeleteService.waitForComplete:  (DEL) {}", LogUtils.elapsedLog(result.getTableName(), result.getEffects(), result.getElapsedTime()));
+        }
+
+        log.info("[DELETE.] LinkTrafDeleteService.waitForComplete: end. {} ms.", elapsedTime);
     }
 
 }

+ 20 - 7
utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafFusionService.java

@@ -25,7 +25,7 @@ import java.util.stream.Collectors;
 @Service
 public class LinkTrafFusionService implements AbstractProcessService {
 
-    private final LinkRepositoryService linkRepositoryService;
+    private final LinkRepositoryService linkRepo;
     private final LinkTrafParamService trafParamService;
     private final LinkTrafCollectService collectService;
 
@@ -41,7 +41,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
         Elapsed elapsed = new Elapsed();
 
         // 0. 링크 소통정보를 초기화 한다.
-        this.linkRepositoryService.initLinkTraf(true);
+        this.linkRepo.initLinkTraf(true);
 
         // 1. 수집된 소통정보를 객체로 초기화 한다.
         this.collectOPER = Optional.ofNullable(this.collectService.get(LinkTrafCollectSetupService.OPER))
@@ -57,6 +57,14 @@ public class LinkTrafFusionService implements AbstractProcessService {
         this.collectMOCT = Optional.ofNullable(this.collectService.get(LinkTrafCollectSetupService.MOCT))
                 .orElseGet(() -> LinkCollectResultDto.builder().clctSystCd(LinkTrafCollectSetupService.MOCT).lists(new ArrayList<>()).build());
 
+        this.linkRepo.getFusionInfo().setColOprCnt(this.collectOPER.getLists().size());
+        this.linkRepo.getFusionInfo().setColUtisCnt(this.collectUTIS.getLists().size());
+        this.linkRepo.getFusionInfo().setColPriCnt(this.collectPRIO.getLists().size());
+        this.linkRepo.getFusionInfo().setColPriEtcCnt(this.collectPRIOETC.getLists().size());
+        this.linkRepo.getFusionInfo().setColDongbuCnt(this.collectDONGBU.getLists().size());
+        this.linkRepo.getFusionInfo().setColMoctCnt(this.collectMOCT.getLists().size());
+        this.linkRepo.getFusionInfo().setColGpsCnt(0);  // GPS 수집정보는 없음
+
         log.info("[FUSION.] LinkTrafFusionService.initialize: ..end. {}", Elapsed.elapsedStr(elapsed.nanoSeconds()));
     }
 
@@ -95,7 +103,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
         Elapsed elapsed = new Elapsed();
 
         AtomicInteger nCalCnt = new AtomicInteger();
-        this.linkRepositoryService.getLinkMap().values().parallelStream()
+        this.linkRepo.getLinkMap().values().parallelStream()
                 .filter(link -> link.getLinkLevel() == 1)
                 .forEach(link -> {
                     TrafficGrade grade = Optional.ofNullable(this.trafParamService.getTrafGradeMap().get(link.getLinkId()))
@@ -108,12 +116,13 @@ public class LinkTrafFusionService implements AbstractProcessService {
                 }
             );
 
+        this.linkRepo.getFusionInfo().setFltSpdCnt(nCalCnt.get());
         log.info("[FUSION.] LinkTrafFusionService.trafficCorrect: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return nCalCnt.get();
     }
 
     private boolean fusionTraffic(LinkCollectDto clctTraf, final String clctSystCd) {
-        LinkDto link = this.linkRepositoryService.getLink(clctTraf.getLinkId());
+        LinkDto link = this.linkRepo.getLink(clctTraf.getLinkId());
         if (link == null) {
             log.error("[FUSION.] LinkTrafFusionService.fusionTraffic: {} link not found[{}].", clctTraf.getLinkId(), clctSystCd);
             return false;
@@ -155,6 +164,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
                     }
                 });
 
+        this.linkRepo.getFusionInfo().setFsnPriCnt(nCalCnt.get());
         log.info("[FUSION.] LinkTrafFusionService.priorityFusion: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return nCalCnt.get();
     }
@@ -178,7 +188,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
         AtomicReference<String> dongbu = new AtomicReference<>("0");
 
         AtomicInteger nCalCnt = new AtomicInteger();
-        this.linkRepositoryService.getLinkMap().values().parallelStream()
+        this.linkRepo.getLinkMap().values().parallelStream()
                 .filter(link -> link.getLinkLevel() == 1)
                 .filter(link -> !link.getTrafFsn().getState().isState())
                 .forEach(link -> {
@@ -235,12 +245,14 @@ public class LinkTrafFusionService implements AbstractProcessService {
                     link.getTrafFsn().setTraffic("L00", speed, "R", weight.getDataResType());
                     nCalCnt.incrementAndGet();
                 });
+
+        this.linkRepo.getFusionInfo().setFsnWgtCnt(nCalCnt.get());
         log.info("[FUSION.] LinkTrafFusionService.weightFusion: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return nCalCnt.get();
     }
 
     private boolean externalFusionTraffic(LinkCollectDto clctTraf, final String clctSystCd) {
-        LinkDto link = this.linkRepositoryService.getLink(clctTraf.getLinkId());
+        LinkDto link = this.linkRepo.getLink(clctTraf.getLinkId());
         if (link == null) {
             log.error("[FUSION.] LinkTrafFusionService.externalFusionTraffic: {} link not found[{}].", clctTraf.getLinkId(), clctSystCd);
             return false;
@@ -285,7 +297,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
         Elapsed elapsed = new Elapsed();
         int nCalCnt = 0;
         for (LinkCollectDto dto : this.collectOPER.getLists()) {
-            LinkDto link = this.linkRepositoryService.getLink(dto.getLinkId());
+            LinkDto link = this.linkRepo.getLink(dto.getLinkId());
             if (link == null) {
                 log.error("[FUSION.] LinkTrafFusionService.operatorFusion: {} link not found.", dto.getLinkId());
                 continue;
@@ -294,6 +306,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
             link.getTrafExt().setTraffic(dto);
             nCalCnt++;
         }
+        this.linkRepo.getFusionInfo().setFsnOprCnt(nCalCnt);
         log.info("[FUSION.] LinkTrafFusionService.operatorFusion: ..end. {} EA. {}", nCalCnt, Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return nCalCnt;
     }

+ 22 - 9
utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafMissingService.java

@@ -24,19 +24,12 @@ public class LinkTrafMissingService implements AbstractProcessService {
     private final LinkRepositoryService linkRepo;
     private final LinkTrafParamService trafParamService;
     private final LinkTrafCollectService collectService;
+    private final LinkTrafPatternService patternService;
 
-    private void initialize() {
-        log.info("[MISSING] LinkTrafMissingService.initialize: start.");
-        Elapsed elapsed = new Elapsed();
-        log.info("[MISSING] LinkTrafMissingService.initialize: ..end. {}", Elapsed.elapsedStr(elapsed.nanoSeconds()));
-    }
     public int processing() {
         log.info("[MISSING] LinkTrafMissingService.processing: start.");
         Elapsed elapsed = new Elapsed();
 
-        // 0. 결측 초기화
-        initialize();
-
         // 모든 결측 알고리즘에 대해 결측 처리를 수행하고 
         // 최종 선택된 결측 알고리즘으로 결측을 수행한다.
         
@@ -100,6 +93,8 @@ public class LinkTrafMissingService implements AbstractProcessService {
                 nCalCnt++;
             }
         }
+
+        this.linkRepo.getFusionInfo().setMissMoctCnt(nCalCnt);
         log.info("[MISSING] LinkTrafMissingService.missingLinkMoct: ..end. {} EA. {}", nCalCnt, Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return nCalCnt;
     }
@@ -141,6 +136,8 @@ public class LinkTrafMissingService implements AbstractProcessService {
         log.info("[MISSING] LinkTrafMissingService.missingLinkPattern: start.");
         Elapsed elapsed = new Elapsed();
 
+        this.linkRepo.getFusionInfo().setColPtnCnt(this.patternService.getPatternCount());
+
         // 결측처리 방식: 구간의 현재 패턴정보를 이용
         AtomicInteger nCalCnt = new AtomicInteger();
         this.linkRepo.getLinkMap().values().parallelStream()
@@ -166,6 +163,7 @@ public class LinkTrafMissingService implements AbstractProcessService {
                         }
                 );
 
+        this.linkRepo.getFusionInfo().setMissPtnCnt(nCalCnt.get());
         log.info("[MISSING] LinkTrafMissingService.missingLinkPattern: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return nCalCnt.get();
     }
@@ -175,12 +173,14 @@ public class LinkTrafMissingService implements AbstractProcessService {
         Elapsed elapsed = new Elapsed();
 
         // 결측처리 방식: 우선순위, KNN(사용하지 않음)
+        AtomicInteger nRealCnt = new AtomicInteger();
         AtomicInteger nCalCnt = new AtomicInteger();
         this.linkRepo.getLinkMap().values().parallelStream()
                 .filter(link -> link.getLinkLevel() == 1)
                 .forEach(link -> {
                             // 구간의 퓨전소통정보가 존재하면 처리하지 않음
                             if (link.getTrafFsn().getState().isState()) {
+                                nRealCnt.incrementAndGet();
                                 return;
                             }
 
@@ -195,6 +195,10 @@ public class LinkTrafMissingService implements AbstractProcessService {
                         }
                 );
 
+        this.linkRepo.getFusionInfo().setRealFsnCnt(nRealCnt.get());
+        this.linkRepo.getFusionInfo().setMissPsdCnt(nCalCnt.get());
+        this.linkRepo.getFusionInfo().setMissKnnCnt(0); // knn 알고리즘 수행하지 않음
+
         log.info("[MISSING] LinkTrafMissingService.missingLinkCorrect: ..end. {} EA. {}", nCalCnt.get(), Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return nCalCnt.get();
     }
@@ -253,12 +257,20 @@ public class LinkTrafMissingService implements AbstractProcessService {
                     if (step == 1 || step == 2) {
                         // 상류부(H) 또는 하류부(L) 소통정보 만 존재하는 경우
                         speed = (int)( (ptrnSpeed * (cSpeed / pSpeed)) + 0.5 );
-                        missValueYn = (step == 1) ? "H" : "L";
+                        if (step == 1) {
+                            missValueYn = "H";
+                            this.linkRepo.getFusionInfo().setPsdUpCnt(this.linkRepo.getFusionInfo().getPsdUpCnt()+1);
+                        }
+                        else {
+                            missValueYn = "L";
+                            this.linkRepo.getFusionInfo().setPsdDnCnt(this.linkRepo.getFusionInfo().getPsdDnCnt()+1);
+                        }
                     }
                     else if (step == 3) {
                         // 상/하류부 소통정보가 모두 존재하는 경우 'Y'
                         speed = (int)( (ptrnSpeed * ((cSpeed/2.) / (pSpeed/2.))) + 0.5 );
                         missValueYn = "Y";
+                        this.linkRepo.getFusionInfo().setPsdUpDnCnt(this.linkRepo.getFusionInfo().getPsdUpDnCnt()+1);
                     }
                     if (speed > 0) {
                         if (speed > link.getMaxSpeed()) {
@@ -380,6 +392,7 @@ public class LinkTrafMissingService implements AbstractProcessService {
                         subLink.getMissPsd().setSpeed(subLink.getMaxSpeed());
                     }
                     nCalCnt.incrementAndGet();
+                    this.linkRepo.getFusionInfo().setPsdLv4Cnt(this.linkRepo.getFusionInfo().getPsdLv4Cnt()+1);
                 }
             }
         );

+ 2 - 0
utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafPatternService.java

@@ -48,6 +48,8 @@ public class LinkTrafPatternService implements AbstractProcessService {
 
     private final ConcurrentHashMap<String, TrafficGrade> trafGradeMap = new ConcurrentHashMap<>();
 
+    private int patternCount = 0;
+
     public int processing() {
         log.info("[PATTERN] processing: start.");
         Elapsed elapsed = new Elapsed();

+ 1 - 1
utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafPrcsTime.java

@@ -243,7 +243,7 @@ public class LinkTrafPrcsTime {
 		int sec   = cal.get(Calendar.SECOND);
 
 		String strCurrTime = String.format("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec);
-		log.info("[PROCESSING] TrafficProcessingTime.init: {}", strCurrTime);
+		log.info("[TIME...] TrafficProcessingTime.init: {}", strCurrTime);
 
 		cal.setTime(convertString2Date(this.prcsFiveMin));		/* 요일, 사사분기는 가공시각을 기준으로 계산 */
 		this.prcsDayWeek   = cal.get(Calendar.DAY_OF_WEEK);		/* DAY_OF_WEEK 리턴값이 일요일(1), 월요일(2), 화요일(3) ~~ 토요일(7)을 반환합니다. */

+ 85 - 1
utic-ptis-server/src/main/java/com/utic/ptis/server/service/LinkTrafSaveService.java

@@ -1,12 +1,24 @@
 package com.utic.ptis.server.service;
 
 import com.utic.common.utils.Elapsed;
+import com.utic.ptis.server.dao.mapper.dwdb.DwdbTrafficMapper;
+import com.utic.ptis.server.dao.mapper.utic.UticTrafficMapper;
+import com.utic.ptis.server.dto.DbmsJobResult;
+import com.utic.ptis.server.service.worker.*;
+import com.utic.ptis.server.utils.LogUtils;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.PostConstruct;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
 @Slf4j
 @Data
 @ToString
@@ -14,14 +26,86 @@ import org.springframework.stereotype.Service;
 @Service
 public class LinkTrafSaveService implements AbstractProcessService {
 
+    public static final String TABLE_TRAFFIC_CENTER = "TRAFFIC_CENTER";
+    public static final String TABLE_TRAFFIC_CENTER_EXT = "TRAFFIC_CENTER_EXT";
+    public static final String TABLE_TRAFFIC_CENTER_HIST = "TRAFFIC_CENTER_HIST@DWDB";
+    public static final String TABLE_LINK_MISSING_VALUE_HIST = "LINK_MISSING_VALUE_HIST@DWDB";
+    public static final String TABLE_LINK_FUSION_LOG = "LINK_FUSION_LOG@DWDB";
+
+    private final LinkRepositoryService linkRepo;
     private final UticSqlSessionService uticSqlSessionService;
+    private final UticTrafficMapper uticMapper;
+    private final DwdbTrafficMapper dwdbMapper;
     private final LinkTrafPrcsTime prcsTime;
     private final LinkRepositoryService linkRepositoryService;
 
+    private ConcurrentHashMap<String, DbmsJobResult> mapData = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void init() {
+        log.info("[SAVE...] LinkTrafSaveService.init: start.");
+        Elapsed elapsed = new Elapsed();
+
+        // 초기화
+        this.mapData.put(TABLE_TRAFFIC_CENTER, DbmsJobResult.builder().tableName(TABLE_TRAFFIC_CENTER).effects(0).elapsedTime(0).build());
+        this.mapData.put(TABLE_TRAFFIC_CENTER_EXT, DbmsJobResult.builder().tableName(TABLE_TRAFFIC_CENTER_EXT).effects(0).elapsedTime(0).build());
+        this.mapData.put(TABLE_TRAFFIC_CENTER_HIST, DbmsJobResult.builder().tableName(TABLE_TRAFFIC_CENTER_HIST).effects(0).elapsedTime(0).build());
+        this.mapData.put(TABLE_LINK_MISSING_VALUE_HIST, DbmsJobResult.builder().tableName(TABLE_LINK_MISSING_VALUE_HIST).effects(0).elapsedTime(0).build());
+        this.mapData.put(TABLE_LINK_FUSION_LOG, DbmsJobResult.builder().tableName(TABLE_LINK_FUSION_LOG).effects(0).elapsedTime(0).build());
+
+        log.info("[SAVE...] LinkTrafSaveService.init: end. {} ms.", elapsed.milliSeconds());
+    }
+
+    private int initialize() {
+        this.mapData.forEach((jobTable, result) -> {
+            result.setEffects(0);
+            result.setElapsedTime(0);
+        });
+
+        long count = this.linkRepo.getLinkMap().values().parallelStream()
+                .filter(link -> link.getLinkLevel() == 1)
+                .filter(link -> link.getTrafFsn().getSpeed() == 0)
+                .count();
+        this.linkRepo.getFusionInfo().setZeroSpdCnt((int)count);
+        return (int)count;
+    }
+
     public int processing() {
         log.info("[SAVE...] LinkTrafSaveService.processing: start.");
         Elapsed elapsed = new Elapsed();
-        log.info("[DELETE.] LinkTrafSaveService.processing: end. {}", Elapsed.elapsedStr(elapsed.nanoSeconds()));
+
+        final int THREAD_POOL_SIZE = 5;     // 작업 스레드 개수 설정
+        final int TIMEOUT_SECONDS = 120;    // 최대 대기 시간 설정
+
+        // 데이터 초기화
+        initialize();
+
+        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
+        executorService.execute(new LinkTrafSaveCenterWorker(this.linkRepo, this.mapData.get(TABLE_TRAFFIC_CENTER), this.uticSqlSessionService.getTrafficSqlSession(), this.prcsTime, this.uticMapper));
+        executorService.execute(new LinkTrafSaveCenterExtWorker(this.linkRepo, this.mapData.get(TABLE_TRAFFIC_CENTER_EXT), this.uticSqlSessionService.getTrafficExtSqlSession(), this.prcsTime, this.uticMapper));
+        executorService.execute(new LinkTrafSaveDwdbCenterHistWorker(this.linkRepo, this.mapData.get(TABLE_TRAFFIC_CENTER_HIST)));
+        executorService.execute(new LinkTrafSaveDwdbMissingValueHistWorker(this.linkRepo, this.mapData.get(TABLE_LINK_MISSING_VALUE_HIST), this.prcsTime, this.dwdbMapper));
+        executorService.execute(new LinkTrafSaveDwdbFusionLogWorker(this.linkRepo, this.mapData.get(TABLE_LINK_FUSION_LOG), this.dwdbMapper));
+
+        try {
+            executorService.shutdown();
+            if (!executorService.awaitTermination(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
+                executorService.shutdownNow();
+            }
+        } catch (InterruptedException e) {
+            log.error("[COLLECT] LinkTrafCollectService.processing: LinkCollectWorker InterruptedException, {}", e.getMessage());
+            executorService.shutdownNow();
+        }
+
+        // 모든 작업이 완료된 후 결과를 출력
+        long elapsedTime = 0;
+        for (Map.Entry<String, DbmsJobResult> entry : this.mapData.entrySet()) {
+            DbmsJobResult result = entry.getValue();
+            elapsedTime = Math.max(elapsedTime, result.getElapsedTime());
+            log.info("[SAVE...] LinkTrafSaveService.processing:  (SAV) {}", LogUtils.elapsedLog(result.getTableName(), result.getEffects(), result.getElapsedTime()));
+        }
+
+        log.info("[SAVE...] LinkTrafSaveService.processing: end. {}", Elapsed.elapsedStr(elapsed.nanoSeconds()));
         return 0;
     }
 

+ 2 - 2
utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafDeleteWorker.java

@@ -1,7 +1,7 @@
 package com.utic.ptis.server.service.worker;
 
 import com.utic.ptis.server.dao.mapper.utic.UticTrafficMapper;
-import com.utic.ptis.server.dto.DbmsJobResultDto;
+import com.utic.ptis.server.dto.DbmsJobResult;
 import com.utic.ptis.server.service.LinkTrafDeleteService;
 import com.utic.ptis.server.utils.LogUtils;
 import lombok.RequiredArgsConstructor;
@@ -13,7 +13,7 @@ import org.springframework.util.StopWatch;
 public class LinkTrafDeleteWorker implements Runnable {
 
     private final String deleteTable;
-    private final DbmsJobResultDto dbmsJobResult;
+    private final DbmsJobResult dbmsJobResult;
     private final UticTrafficMapper mapper;
 
     @Override

+ 52 - 0
utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveCenterExtWorker.java

@@ -0,0 +1,52 @@
+package com.utic.ptis.server.service.worker;
+
+import com.utic.ptis.server.dao.mapper.utic.UticTrafficMapper;
+import com.utic.ptis.server.dto.DbmsJobResult;
+import com.utic.ptis.server.service.LinkRepositoryService;
+import com.utic.ptis.server.service.LinkTrafPrcsTime;
+import com.utic.ptis.server.utils.LogUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.session.SqlSession;
+import org.springframework.util.StopWatch;
+
+@Slf4j
+@RequiredArgsConstructor
+public class LinkTrafSaveCenterExtWorker implements Runnable {
+
+    private final LinkRepositoryService linkRepo;
+    private final DbmsJobResult dbmsJobResult;
+    private final SqlSession sqlSession;
+    private final LinkTrafPrcsTime prcsTime;
+    private final UticTrafficMapper mapper;
+
+    @Override
+    public void run() {
+        String jobTable = this.dbmsJobResult.getTableName();
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start(jobTable);
+        int resultCount = 0;
+//        try {
+//            Thread.sleep(10);
+//
+//            if (LinkTrafDeleteService.TABLE_TRAFFIC_CENTER.equals(this.jobTable)) {
+//                resultCount = this.mapper.deleteTrafficCenter();
+//            }
+//            else if (LinkTrafDeleteService.TABLE_TRAFFIC_CENTER_EXT.equals(this.jobTable)) {
+//                resultCount = this.mapper.deleteTrafficCenterExt();
+//            }
+//        }
+//        catch (InterruptedException e) {
+//            log.info("[DELETE.] LinkTrafDeleteWorker.run: InterruptedException, [{}], {}.", this.jobTable, e.getMessage());
+//        }
+//        catch (Exception e) {
+//            log.info("[DELETE.] LinkTrafDeleteWorker.run: Exception, [{}], {}.", this.jobTable, e.getMessage());
+//        }
+
+        stopWatch.stop();
+        this.dbmsJobResult.setEffects(resultCount);
+        this.dbmsJobResult.setElapsedTime(stopWatch.getTotalTimeMillis());
+        log.info("[SAVE...] LinkTrafSaveCenterExtWorker.run:  (SAV) {}", LogUtils.elapsedLog(jobTable, resultCount, stopWatch.getTotalTimeMillis()));
+    }
+
+}

+ 52 - 0
utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveCenterWorker.java

@@ -0,0 +1,52 @@
+package com.utic.ptis.server.service.worker;
+
+import com.utic.ptis.server.dao.mapper.utic.UticTrafficMapper;
+import com.utic.ptis.server.dto.DbmsJobResult;
+import com.utic.ptis.server.service.LinkRepositoryService;
+import com.utic.ptis.server.service.LinkTrafPrcsTime;
+import com.utic.ptis.server.utils.LogUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.session.SqlSession;
+import org.springframework.util.StopWatch;
+
+@Slf4j
+@RequiredArgsConstructor
+public class LinkTrafSaveCenterWorker implements Runnable {
+
+    private final LinkRepositoryService linkRepo;
+    private final DbmsJobResult dbmsJobResult;
+    private final SqlSession sqlSession;
+    private final LinkTrafPrcsTime prcsTime;
+    private final UticTrafficMapper mapper;
+
+    @Override
+    public void run() {
+        String jobTable = this.dbmsJobResult.getTableName();
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start(jobTable);
+        int resultCount = 0;
+//        try {
+//            Thread.sleep(10);
+//
+//            if (LinkTrafDeleteService.TABLE_TRAFFIC_CENTER.equals(this.jobTable)) {
+//                resultCount = this.mapper.deleteTrafficCenter();
+//            }
+//            else if (LinkTrafDeleteService.TABLE_TRAFFIC_CENTER_EXT.equals(this.jobTable)) {
+//                resultCount = this.mapper.deleteTrafficCenterExt();
+//            }
+//        }
+//        catch (InterruptedException e) {
+//            log.info("[DELETE.] LinkTrafDeleteWorker.run: InterruptedException, [{}], {}.", this.jobTable, e.getMessage());
+//        }
+//        catch (Exception e) {
+//            log.info("[DELETE.] LinkTrafDeleteWorker.run: Exception, [{}], {}.", this.jobTable, e.getMessage());
+//        }
+
+        stopWatch.stop();
+        this.dbmsJobResult.setEffects(resultCount);
+        this.dbmsJobResult.setElapsedTime(stopWatch.getTotalTimeMillis());
+        log.info("[SAVE...] LinkTrafSaveCenterWorker.run:  (SAV) {}", LogUtils.elapsedLog(jobTable, resultCount, stopWatch.getTotalTimeMillis()));
+    }
+
+}

+ 147 - 0
utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveDwdbCenterHistWorker.java

@@ -0,0 +1,147 @@
+package com.utic.ptis.server.service.worker;
+
+import com.utic.common.spring.SpringUtils;
+import com.utic.ptis.server.dao.mapper.dwdb.DwdbTrafficMapper;
+import com.utic.ptis.server.dto.DbmsBatchJobResult;
+import com.utic.ptis.server.dto.DbmsJobResult;
+import com.utic.ptis.server.dto.LinkDto;
+import com.utic.ptis.server.dto.LinkTrafCenterDto;
+import com.utic.ptis.server.service.LinkRepositoryService;
+import com.utic.ptis.server.utils.LogUtils;
+import lombok.RequiredArgsConstructor;
+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.util.StopWatch;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@RequiredArgsConstructor
+public class LinkTrafSaveDwdbCenterHistWorker implements Runnable {
+
+    private final LinkRepositoryService linkRepo;
+    private final DbmsJobResult dbmsJobResult;
+
+    @Override
+    public void run() {
+        String jobTable = this.dbmsJobResult.getTableName();
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start(jobTable);
+        ConcurrentHashMap<Integer, DbmsBatchJobResult> mapData = new ConcurrentHashMap<>();
+        SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) SpringUtils.getBean("dwdbSqlSessionFactory");
+
+        int linkTotalCount = this.linkRepo.getLinkArr().length;
+        int threadPoolSize = this.linkRepo.getConfig().getPrcsThreadCount();
+        int batchPerThread = (int) Math.ceil((double) linkTotalCount / threadPoolSize);
+
+        for (int ii = 0; ii < threadPoolSize; ii++) {
+            int startIdx = ii * batchPerThread;
+            int endIdx = Math.min(startIdx + batchPerThread, linkTotalCount);
+            DbmsBatchJobResult dbmsJobResult = DbmsBatchJobResult.builder()
+                    .jobIndex(ii).start(startIdx).end(endIdx)
+                    .total(0).target(0).link1(0).link2(0).link3(0).link4(0).effects(0).elapsedTime(0)
+                    .build();
+            mapData.put(ii, dbmsJobResult);
+            log.info("[SAVE...] LinkTrafSaveDwdbCenterHistWorker.run: [{}], {}", jobTable, dbmsJobResult);
+        }
+        ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
+
+        try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
+            DwdbTrafficMapper mapper = sqlSession.getMapper(DwdbTrafficMapper.class);
+            mapData.forEach((key, dbmsJobResult) -> {
+                executorService.execute(() -> processBatch(sqlSession, dbmsJobResult, this.linkRepo, mapper));
+            });
+
+            try {
+                executorService.shutdown();
+                if (!executorService.awaitTermination(100, TimeUnit.SECONDS)) {
+                    executorService.shutdownNow();
+                }
+            } catch (InterruptedException e) {
+                log.error("[SAVE...] LinkTrafSaveDwdbCenterHistWorker.run: InterruptedException, [{}], {}.", jobTable, e.getMessage());
+                executorService.shutdownNow();
+            }
+            sqlSession.commit();
+        }
+        catch (Exception e) {
+            log.info("[SAVE...] LinkTrafSaveDwdbCenterHistWorker.run: Exception, [{}], {}.", jobTable, e.getMessage());
+        }
+
+        int resultCount = 0;
+
+        stopWatch.stop();
+        this.dbmsJobResult.setEffects(resultCount);
+        this.dbmsJobResult.setElapsedTime(stopWatch.getTotalTimeMillis());
+        log.info("[SAVE...] LinkTrafSaveDwdbCenterHistWorker.run:  (SAV) {}", LogUtils.elapsedLog(jobTable, resultCount, stopWatch.getTotalTimeMillis()));
+    }
+
+    private void processBatch(SqlSession sqlSession, DbmsBatchJobResult dbmsJobResult, LinkRepositoryService linkRepo, DwdbTrafficMapper mapper) {
+        final String mapperName = "insertTrafficCenterHist";
+        final int maxBatchSize = linkRepo.getConfig().getDbmsBatchSize();
+        int total, target;
+        int[] linkCounts = new int[4];
+        int jobCnt = 0;
+        total = target = linkCounts[0] = linkCounts[1] = linkCounts[2] = linkCounts[3] = 0;
+
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start(mapperName + dbmsJobResult.getJobIndex());
+
+        log.info("[SAVE...] LinkTrafSaveDwdbCenterHistWorker.processBatch: [{}], {} EA. {}", dbmsJobResult.getJobIndex(), dbmsJobResult.getEnd() - dbmsJobResult.getStart(), dbmsJobResult);
+        for (int ii = dbmsJobResult.getStart(); ii < dbmsJobResult.getEnd(); ii++) {
+            String linkId = linkRepo.getLinkArr()[ii];
+            LinkDto link = linkRepo.getLinkMap().get(linkId);
+            if (link == null) {
+                log.error("[SAVE...] LinkTrafSaveDwdbCenterHistWorker.processBatch: Link is null, [{}].", linkId);
+                continue;
+            }
+            total++;
+
+//            if (!link.getTrafFsn().getState().isState()) {
+//                continue;
+//            }
+            target++;
+
+            LinkTrafCenterDto trafDto = null;
+            try {
+                trafDto = link.getTrafficDto(linkRepo.getPrcsTime());
+//                sqlSession.insert(mapperName, trafDto);
+                mapper.insertTrafficCenterHist(trafDto);
+                linkCounts[trafDto.getLinkLevel()-1]++;
+                jobCnt++;
+
+                if (jobCnt % maxBatchSize == 0) {
+//                    synchronized (sqlSession) {
+//                        sqlSession.flushStatements();
+//                        sqlSession.clearCache();
+//                    }
+                }
+            } catch (Exception e) {
+                log.error("[SAVE...] LinkTrafSaveDwdbCenterHistWorker.processBatch: Exception, [{}], {}.", trafDto, e.getMessage());
+                break;
+            }
+        }
+//        synchronized (sqlSession) {
+//            sqlSession.flushStatements();
+//            sqlSession.clearCache();
+//            sqlSession.commit();
+//        }
+        stopWatch.stop();
+
+        dbmsJobResult.setTotal(total);
+        dbmsJobResult.setTarget(target);
+        dbmsJobResult.setLink1(linkCounts[0]);
+        dbmsJobResult.setLink2(linkCounts[1]);
+        dbmsJobResult.setLink3(linkCounts[2]);
+        dbmsJobResult.setLink4(linkCounts[3]);
+        dbmsJobResult.setEffects(jobCnt);
+        dbmsJobResult.setElapsedTime(stopWatch.getTotalTimeMillis());
+        log.info("[SAVE...] LinkTrafSaveDwdbCenterHistWorker.processBatch: (SAV) {}, {}",
+                LogUtils.elapsedLog(mapperName + dbmsJobResult.getJobIndex(), jobCnt, stopWatch.getTotalTimeMillis()), dbmsJobResult);
+    }
+
+}

+ 45 - 0
utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveDwdbFusionLogWorker.java

@@ -0,0 +1,45 @@
+package com.utic.ptis.server.service.worker;
+
+import com.utic.ptis.server.dao.mapper.dwdb.DwdbTrafficMapper;
+import com.utic.ptis.server.dto.DbmsJobResult;
+import com.utic.ptis.server.dto.LinkTrafFusionInfo;
+import com.utic.ptis.server.service.LinkRepositoryService;
+import com.utic.ptis.server.utils.LogUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.StopWatch;
+
+@Slf4j
+@RequiredArgsConstructor
+public class LinkTrafSaveDwdbFusionLogWorker implements Runnable {
+
+    private final LinkRepositoryService linkRepo;
+    private final DbmsJobResult dbmsJobResult;
+    private final DwdbTrafficMapper mapper;
+
+    @Override
+    public void run() {
+        String jobTable = this.dbmsJobResult.getTableName();
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start(jobTable);
+
+        int resultCount = 0;
+        try {
+            Thread.sleep(10);
+            LinkTrafFusionInfo obj = this.linkRepo.getFusionInfo();
+            resultCount = this.mapper.insertLinkFusionLog(obj);
+        }
+        catch (InterruptedException e) {
+            log.info("[DELETE.] LinkTrafSaveDwdbFusionLogWorker.run: InterruptedException, [{}], {}.", jobTable, e.getMessage());
+        }
+        catch (Exception e) {
+            log.info("[DELETE.] LinkTrafSaveDwdbFusionLogWorker.run: Exception, [{}], {}.", jobTable, e.getMessage());
+        }
+
+        stopWatch.stop();
+        this.dbmsJobResult.setEffects(resultCount);
+        this.dbmsJobResult.setElapsedTime(stopWatch.getTotalTimeMillis());
+        log.info("[SAVE...] LinkTrafSaveDwdbFusionLogWorker.run:  (SAV) {}", LogUtils.elapsedLog(jobTable, resultCount, stopWatch.getTotalTimeMillis()));
+    }
+
+}

+ 50 - 0
utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveDwdbMissingValueHistWorker.java

@@ -0,0 +1,50 @@
+package com.utic.ptis.server.service.worker;
+
+import com.utic.ptis.server.dao.mapper.dwdb.DwdbTrafficMapper;
+import com.utic.ptis.server.dto.DbmsJobResult;
+import com.utic.ptis.server.service.LinkRepositoryService;
+import com.utic.ptis.server.service.LinkTrafPrcsTime;
+import com.utic.ptis.server.utils.LogUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.StopWatch;
+
+@Slf4j
+@RequiredArgsConstructor
+public class LinkTrafSaveDwdbMissingValueHistWorker implements Runnable {
+
+    private final LinkRepositoryService linkRepo;
+    private final DbmsJobResult dbmsJobResult;
+    private final LinkTrafPrcsTime prcsTime;
+    private final DwdbTrafficMapper mapper;
+
+    @Override
+    public void run() {
+        String jobTable = this.dbmsJobResult.getTableName();
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start(jobTable);
+        int resultCount = 0;
+//        try {
+//            Thread.sleep(10);
+//
+//            if (LinkTrafDeleteService.TABLE_TRAFFIC_CENTER.equals(this.jobTable)) {
+//                resultCount = this.mapper.deleteTrafficCenter();
+//            }
+//            else if (LinkTrafDeleteService.TABLE_TRAFFIC_CENTER_EXT.equals(this.jobTable)) {
+//                resultCount = this.mapper.deleteTrafficCenterExt();
+//            }
+//        }
+//        catch (InterruptedException e) {
+//            log.info("[DELETE.] LinkTrafDeleteWorker.run: InterruptedException, [{}], {}.", this.jobTable, e.getMessage());
+//        }
+//        catch (Exception e) {
+//            log.info("[DELETE.] LinkTrafDeleteWorker.run: Exception, [{}], {}.", this.jobTable, e.getMessage());
+//        }
+
+        stopWatch.stop();
+        this.dbmsJobResult.setEffects(resultCount);
+        this.dbmsJobResult.setElapsedTime(stopWatch.getTotalTimeMillis());
+        log.info("[SAVE...] LinkTrafSaveDwdbMissingValueHistWorker.run:  (SAV) {}", LogUtils.elapsedLog(jobTable, resultCount, stopWatch.getTotalTimeMillis()));
+    }
+
+}

+ 0 - 46
utic-ptis-server/src/main/java/com/utic/ptis/server/service/worker/LinkTrafSaveWorker.java

@@ -1,46 +0,0 @@
-package com.utic.ptis.server.service.worker;
-
-import com.utic.ptis.server.dao.mapper.utic.UticTrafficMapper;
-import com.utic.ptis.server.dto.DbmsJobResultDto;
-import com.utic.ptis.server.service.LinkTrafDeleteService;
-import com.utic.ptis.server.utils.LogUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.util.StopWatch;
-
-@Slf4j
-@RequiredArgsConstructor
-public class LinkTrafSaveWorker implements Runnable {
-
-    private final String deleteTable;
-    private final DbmsJobResultDto dbmsJobResult;
-    private final UticTrafficMapper mapper;
-
-    @Override
-    public void run() {
-        StopWatch stopWatch = new StopWatch();
-        stopWatch.start(this.deleteTable);
-        int resultCount = 0;
-        try {
-            Thread.sleep(10);
-
-            if (LinkTrafDeleteService.TABLE_TRAFFIC_CENTER.equals(this.deleteTable)) {
-                resultCount = this.mapper.deleteTrafficCenter();
-            }
-            else if (LinkTrafDeleteService.TABLE_TRAFFIC_CENTER_EXT.equals(this.deleteTable)) {
-                resultCount = this.mapper.deleteTrafficCenterExt();
-            }
-        }
-        catch (InterruptedException e) {
-            log.info("[DELETE.] LinkTrafDeleteWorker.run: InterruptedException, [{}], {}.", this.deleteTable, e.getMessage());
-        }
-        catch (Exception e) {
-            log.info("[DELETE.] LinkTrafDeleteWorker.run: Exception, [{}], {}.", this.deleteTable, e.getMessage());
-        }
-        stopWatch.stop();
-        this.dbmsJobResult.setEffects(resultCount);
-        this.dbmsJobResult.setElapsedTime(stopWatch.getTotalTimeMillis());
-        log.info("[DELETE.] LinkTrafDeleteWorker.run:  (DEL) {}", LogUtils.elapsedLog(this.deleteTable, resultCount, stopWatch.getTotalTimeMillis()));
-    }
-
-}

+ 1 - 0
utic-ptis-server/src/main/resources/application.yml

@@ -49,6 +49,7 @@ application:
   process-id: 70030
   err-time-gap: 300
   prcs-thread-count: 10
+  dbms-batch-size: 1000
 
   packet-workers: 0
   dbms-workers: 1

+ 59 - 64
utic-ptis-server/src/main/resources/mybatis/mapper/dwdb/DwdbTrafficMapper.xml

@@ -3,8 +3,7 @@
 
 <mapper namespace="com.utic.ptis.server.dao.mapper.dwdb.DwdbTrafficMapper">
 
-    <insert id="insertTrafficCenterHist" parameterType="com.utic.ptis.server.dto.LinkTrafCenterHistDto">
-    <![CDATA[
+    <insert id="insertTrafficCenterHist" parameterType="com.utic.ptis.server.dto.LinkTrafCenterDto">
         INSERT /*+ APPEND PARALLEL(TRAFFIC_CENTER_HIST, 2) */ INTO TRAFFIC_CENTER_HIST NOLOGGING (
                         regdate        ,
                         linkid         ,
@@ -22,25 +21,24 @@
                         knncnt
                         )
         VALUES(
-            #{linkId},
-            #{missValueYn},
-            TO_DATE(#{regDate}, 'YYYYMMDDHH24MISS'),
-            #{linkLevel},
-            #{speed},
-            #{travelTime},
-            #{trafficGrade},
-            #{dataResType},
-            #{centerId},
-            #{psdMissValueYn},
-            DECODE(#{psdSpeed},   0, NULL, #{psdSpeed}),
-            DECODE(#{knnSpeed},   0, NULL, #{knnSpeed}),
-            DECODE(#{knnCnt},     0, NULL, #{knnCnt})
+            TO_DATE(#{obj.regDate}, 'YYYYMMDDHH24MISS'),
+            #{obj.linkId},
+            #{obj.missValueYn, jdbcType=NULL},
+            #{obj.linkLevel},
+            #{obj.speed},
+            #{obj.travelTime},
+            #{obj.trafficGrade},
+            #{obj.incidentId, jdbcType=NULL},
+            #{obj.dataResType, jdbcType=NULL},
+            #{obj.centerId},
+            #{obj.psdMissValueYn, jdbcType=NULL},
+            DECODE(#{obj.psdSpeed}, 0, NULL, #{obj.psdSpeed}),
+            DECODE(#{obj.knnSpeed}, 0, NULL, #{obj.knnSpeed}),
+            DECODE(#{obj.knnCnt},   0, NULL, #{obj.knnCnt})
             )
-        ]]>
     </insert>
 
     <insert id="insertLinkFusionLog" parameterType="com.utic.ptis.server.dto.LinkTrafFusionInfo">
-    <![CDATA[
         INSERT INTO LINK_FUSION_LOG (
             REGDATE,
             PRCSTYPE,
@@ -70,38 +68,36 @@
             ZEROSPD
         )
         VALUES(
-                  TO_DATE(#{regDate}, 'YYYYMMDDHH24MISS'),
-                  #{prcsType},
-                  #{linkCnt},
-                  #{colOprCnt},
-                  #{colMoctCnt},
-                  #{colGpsCnt},
-                  #{colUtisCnt},
-                  #{colPriCnt},
-                  #{colPriEtcCnt},
-                  #{colDongbuCnt},
-                  #{colPtnCnt},
-                  #{fsnOprCnt},
-                  #{fsnPriCnt},
-                  #{fsnWgtCnt},
-                  #{missKnnCnt},
-                  #{missPsdCnt},
-                  #{missPtnCnt},
-                  #{missMoctCnt},
-                  #{missGgCnt},
-                  #{knnCnt},
-                  #{psdUpCnt},
-                  #{psdDnCnt},
-                  #{psdUpDnCnt},
-                  #{psdLv4Cnt},
-                  #{fltSpdCnt},
-                  #{zeroSpdCnt}
+                  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.ptis.server.dto.LinkMissingValueHist">
-    <![CDATA[
         INSERT /*+ APPEND PARALLEL(LINK_MISSING_VALUE_HIST, 2) */ INTO LINK_MISSING_VALUE_HIST NOLOGGING (
                     linkid          ,
                     exe_date        ,
@@ -122,25 +118,24 @@
                     knncnt
                     )
         VALUES(
-            #{linkId},
-            #{exeDate},
-            DECODE(#{l4LinkSpd},   0, NULL, #{l4LinkSpd}),
-            DECODE(#{upLinkSpd},   0, NULL, #{upLinkSpd}),
-            DECODE(#{dnLinkSpd},   0, NULL, #{dnLinkSpd}),
-            DECODE(#{l4PatnSpd},   0, NULL, #{l4PatnSpd}),
-            DECODE(#{upPatnSpd},   0, NULL, #{upPatnSpd}),
-            DECODE(#{dnPatnSpd},   0, NULL, #{dnPatnSpd}),
-            DECODE(#{linkPatnSpd}, 0, NULL, #{linkPatnSpd}),
-            #{missingType},
-            DECODE(#{revisionSpd}, 0, NULL, #{revisionSpd}),
-            #{l4LinkId},
-            #{upLinkId},
-            #{dnLinkId},
-            DECODE(#{psdSpeed},   0, NULL, #{psdSpeed}),
-            DECODE(#{knnSpeed},   0, NULL, #{knnSpeed}),
-            DECODE(#{knnCnt},     0, NULL, #{knnCnt})
-            );
-        ]]>
+            #{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>

+ 18 - 22
utic-ptis-server/src/main/resources/mybatis/mapper/utic/UticTrafficMapper.xml

@@ -16,7 +16,6 @@
     </delete>
 
     <insert id="insertTrafficCenter" parameterType="com.utic.ptis.server.dto.LinkTrafCenterDto">
-    <![CDATA[
         INSERT /*+ APPEND PARALLEL(TRAFFIC_CENTER, 2) */ INTO TRAFFIC_CENTER NOLOGGING (
                         linkid       ,
                         missvalueyn  ,
@@ -29,21 +28,19 @@
                         centerid
                         )
         VALUES(
-            #{linkId},
-            #{missValueYn},
-            TO_DATE(#{regDate}, 'YYYYMMDDHH24MISS'),
-            #{linkLevel},
-            #{speed},
-            #{travelTime},
-            #{trafficGrade},
-            #{dataResType},
-            #{centerId}
+            #{obj.linkId},
+            #{obj.missValueYn},
+            TO_DATE(#{obj.regDate}, 'YYYYMMDDHH24MISS'),
+            #{obj.linkLevel},
+            #{obj.speed},
+            #{obj.travelTime},
+            #{obj.trafficGrade},
+            #{obj.dataResType},
+            #{obj.centerId}
             )
-        ]]>
     </insert>
 
     <insert id="insertTrafficCenterExt" parameterType="com.utic.ptis.server.dto.LinkTrafCenterDto">
-    <![CDATA[
         INSERT /*+ APPEND PARALLEL(TRAFFIC_CENTER_EXT, 2) */ INTO TRAFFIC_CENTER_EXT NOLOGGING (
                         linkid       ,
                         missvalueyn  ,
@@ -56,17 +53,16 @@
                         centerid
                         )
         VALUES(
-            #{linkId},
-            #{missValueYn},
-            TO_DATE(#{regDate}, 'YYYYMMDDHH24MISS'),
-            #{linkLevel},
-            #{speed},
-            #{travelTime},
-            #{trafficGrade},
-            #{dataResType},
-            #{centerId}
+            #{obj.linkId},
+            #{obj.missValueYn},
+            TO_DATE(#{obj.regDate}, 'YYYYMMDDHH24MISS'),
+            #{obj.linkLevel},
+            #{obj.speed},
+            #{obj.travelTime},
+            #{obj.trafficGrade},
+            #{obj.dataResType},
+            #{obj.centerId}
             )
-        ]]>
     </insert>
 
 </mapper>

+ 2 - 1
utic-ptis-server/src/main/resources/mybatis/mybatis-config.xml

@@ -12,11 +12,12 @@
 		<setting name="defaultStatementTimeout" value="120000"/>
 		<setting name="returnInstanceForEmptyRow" value="true"/>
 
-		<!-- 카멜 케이스 VO 매핑 -->
 		<setting name="mapUnderscoreToCamelCase" value="false"/>
 		<!--<setting name="mapUnderscoreToCamelCase" value="false"/>-->
+
 		<!-- 쿼리 결과 필드가 null 인 경우, 누락이 되서 나오지 않게 설정-->
 		<setting name="callSettersOnNulls" value="true"/>
+
 		<!-- 쿼리에 보내는 파라미터가 null 인 경우, 오류가 발생하는 것 방지 -->
 		<setting name="jdbcTypeForNull" value="NULL"/>