HANTE 2 ay önce
ebeveyn
işleme
0c78bbaa34
18 değiştirilmiş dosya ile 278 ekleme ve 82 silme
  1. 3 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/mapper/utic/UticTrafficMapper.java
  2. 8 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/repository/utic/UticTrafficRepository.java
  3. 16 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/LinkClctMoctDto.java
  4. 0 7
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/LinkMissingValueHistDto.java
  5. 4 4
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/LinkTrafVal.java
  6. 28 28
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkService.java
  7. 22 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafCollectService.java
  8. 11 6
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafFusionService.java
  9. 4 7
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafMissingService.java
  10. 1 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafPrcsAfterService.java
  11. 2 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveCacheService.java
  12. 37 0
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveCenterService.java
  13. 23 8
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveDwdbService.java
  14. 16 12
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/worker/LinkTrafCollectWorker.java
  15. 12 3
      utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/worker/LinkTrafSaveCacheWorker.java
  16. 3 3
      utic-traf-server/src/main/resources/mybatis/mapper/utic/LinkMapper.xml
  17. 50 3
      utic-traf-server/src/main/resources/mybatis/mapper/utic/UticTrafficMapper.xml
  18. 38 1
      utic-traf-server/src/main/resources/mybatis/mapper/utic/collect/LinkCollectMoct.xml

+ 3 - 0
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/mapper/utic/UticTrafficMapper.java

@@ -19,4 +19,7 @@ public interface UticTrafficMapper {
     int deleteTrafficCenter();
     int insertTrafficCenter();
 
+    int mergeTrafficCenter();
+    int deleteTrafficCenterByDate(@Param("prcsTime") String prcsTime);
+
 }

+ 8 - 0
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dao/repository/utic/UticTrafficRepository.java

@@ -49,4 +49,12 @@ public class UticTrafficRepository {
         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);
+    }
 }

+ 16 - 0
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/LinkClctMoctDto.java

@@ -0,0 +1,16 @@
+package com.utic.center.utic.traf.server.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor//(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
+public class LinkClctMoctDto {
+    private String linkId;
+    private boolean valid;
+    private int speed;
+}

+ 0 - 7
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/LinkMissingValueHistDto.java

@@ -32,10 +32,6 @@ public class LinkMissingValueHistDto implements Serializable {
         this.l4LinkId = link.getLink4Id();
         this.upLinkId = link.getUpLinkId();
         this.dnLinkId = link.getDnLinkId();
-        init();
-    }
-
-    public void init() {
         this.l4LinkSpd = 0;
         this.upLinkSpd = 0;
         this.dnLinkSpd = 0;
@@ -45,9 +41,6 @@ public class LinkMissingValueHistDto implements Serializable {
         this.linkPatnSpd = 0;
         this.missingType = "";
         this.revisionSpd = 0;
-        this.l4LinkId = "";
-        this.upLinkId = "";
-        this.dnLinkId = "";
         this.psdSpeed = 0;
         this.knnSpeed = 0;
         this.knnCnt = 0;

+ 4 - 4
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/dto/LinkTrafVal.java

@@ -43,16 +43,16 @@ public class LinkTrafVal implements Serializable {
 //        return dto;
 //    }
 
-    public void setTraffic(LinkCollectDto traffic) {
-        setTraffic(traffic.getCenterId(), traffic.getSpeed(), traffic.getMissValueYn(), traffic.getDataResType());
+    public void setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE crtDataType, LinkCollectDto traffic) {
+        setTraffic(crtDataType, traffic.getCenterId(), traffic.getSpeed(), traffic.getMissValueYn(), traffic.getDataResType());
     }
-    public void setTraffic(String centerId, Integer speed, String missValueYn, String dataResType) {
+    public void setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE crtDataType, String centerId, Integer speed, String missValueYn, String dataResType) {
         this.centerId = centerId;
         this.speed = speed;
         this.travelTime = 0;
 
         this.state.setState(true);
-        this.state.setCrtDataType(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL);
+        this.state.setCrtDataType(crtDataType);
         this.state.setMissValueYn(missValueYn);
         this.state.setDataResType(dataResType);
         this.state.setTrafficGrade(0);

+ 28 - 28
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkService.java

@@ -126,10 +126,13 @@ public class LinkService implements AbstractProcessService {
             for (LogicalLinkDto logicalLinkDto : links) {
                 String logicalLinkId = logicalLinkDto.getLogicalLinkId();
                 LinkDto logicalLink = this.linkMap.get(logicalLinkId);
-                if (logicalLink != null) {
-                    logicalLink.setLinkIds(logicalLinkDto.getLinkIds());
+                if (logicalLink == null) {
+                    continue;
                 }
-                else {
+
+                logicalLink.setLinkIds(logicalLinkDto.getLinkIds());
+
+                if (linkLevel != 4) {
                     continue;
                 }
 
@@ -139,29 +142,28 @@ public class LinkService implements AbstractProcessService {
                 }
 
                 // 레벨 4일경우에만 해도 됌.
-                if (linkLevel == 4) {
-                    for (int ii = 0; ii < logicalLinkDto.getLinkIds().size(); ii++) {
-                        String linkId = logicalLinkDto.getLinkIds().get(ii);
-                        LinkDto link = this.linkMap.get(linkId);
-                        if (link == null) {
-//                            log.error("[INIT] findLogicalLinkAll: LogicalLink({}), Level({}), Link({}) is null.", logicalLinkId, linkLevel, linkId);
-                            continue;
-                        }
-
-                        link.setLink4Id(logicalLink.getLinkId());
-                        if (ii == 0) {
-                            // 첫번째
-                            link.setUpLinkId(logicalLinkDto.getLinkIds().get(ii + 1));
-                        } else if (ii == linkCount - 1) {
-                            // 마지막
-                            link.setDnLinkId(logicalLinkDto.getLinkIds().get(ii - 1));
-                        } else {
-                            // 중간
-                            link.setUpLinkId(logicalLinkDto.getLinkIds().get(ii + 1));
-                            link.setDnLinkId(logicalLinkDto.getLinkIds().get(ii - 1));
-                        }
-                        calCnt++;
+                for (int ii = 0; ii < logicalLinkDto.getLinkIds().size(); ii++) {
+                    String linkId = logicalLinkDto.getLinkIds().get(ii);
+                    LinkDto link = this.linkMap.get(linkId);
+                    if (link == null) {
+                        continue;
                     }
+
+                    link.setLink4Id(logicalLinkId);
+                    if (ii == 0) {
+                        // 첫번째
+                        link.setUpLinkId(logicalLinkDto.getLinkIds().get(ii + 1));
+                        link.setDnLinkId("");
+                    } else if (ii == (linkCount - 1)) {
+                        // 마지막
+                        link.setUpLinkId("");
+                        link.setDnLinkId(logicalLinkDto.getLinkIds().get(ii - 1));
+                    } else {
+                        // 중간
+                        link.setUpLinkId(logicalLinkDto.getLinkIds().get(ii + 1));
+                        link.setDnLinkId(logicalLinkDto.getLinkIds().get(ii - 1));
+                    }
+                    calCnt++;
                 }
             }
             if (linkLevel == 4) {
@@ -281,10 +283,10 @@ public class LinkService implements AbstractProcessService {
             // 패턴값
             valueHist.setLinkPatnSpd(link.getTrafPtrn().getSpeed());
         }
+
         LinkDto upLink = this.linkMap.get(link.getUpLinkId());
         if (upLink != null) {
             // 상류부 링크
-            valueHist.setUpLinkId(upLink.getUpLinkId());
             if (upLink.getTrafFsn().getState().isState() && upLink.getTrafFsn().getState().getCrtDataType() == LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL) {
                 valueHist.setUpLinkSpd(upLink.getTrafFsn().getSpeed());
             }
@@ -295,7 +297,6 @@ public class LinkService implements AbstractProcessService {
         LinkDto dnLink = this.linkMap.get(link.getDnLinkId());
         if (dnLink != null) {
             // 상류부 링크
-            valueHist.setDnLinkId(dnLink.getDnLinkId());
             if (dnLink.getTrafFsn().getState().isState() && dnLink.getTrafFsn().getState().getCrtDataType() == LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL) {
                 valueHist.setDnLinkSpd(dnLink.getTrafFsn().getSpeed());
             }
@@ -306,7 +307,6 @@ public class LinkService implements AbstractProcessService {
         LinkDto grpLink = this.linkMap.get(link.getLink4Id());
         if (grpLink != null) {
             // 레벨4 링크
-            valueHist.setL4LinkId(link.getLink4Id());
             if (grpLink.getTrafFsn().getState().isState() && grpLink.getTrafFsn().getState().getCrtDataType() == LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL) {
                 valueHist.setL4LinkSpd(grpLink.getTrafFsn().getSpeed());
             }

+ 22 - 0
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafCollectService.java

@@ -4,6 +4,7 @@ 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.config.TraceConfig;
+import com.utic.center.utic.traf.server.dto.LinkClctMoctDto;
 import com.utic.center.utic.traf.server.dto.LinkCollectParam;
 import com.utic.center.utic.traf.server.dto.LinkCollectResultDto;
 import com.utic.center.utic.traf.server.dto.LinkCollectSetupDto;
@@ -31,11 +32,17 @@ public class LinkTrafCollectService implements AbstractProcessService {
     private final LinkTrafCollectSetupService collectSetupService;
 
     private ConcurrentHashMap<String, LinkCollectResultDto> mapData = new ConcurrentHashMap<>();
+    private ConcurrentHashMap<String, LinkClctMoctDto> moctMap = new ConcurrentHashMap<>();
 
     public LinkCollectResultDto get(String key) {
         return this.mapData.get(key);
     }
 
+    public void initCollectTraf() {
+        this.moctMap.values().parallelStream()
+                .forEach(clct -> clct.setValid(false));
+    }
+
     public void initialize() {
         // 수집원 별 수집 데이터 초기화
         for (String id: this.mapData.keySet()) {
@@ -93,6 +100,21 @@ public class LinkTrafCollectService implements AbstractProcessService {
                 }
                 else if (LinkTrafCollectSetupService.MOCT.equals(collect.getClctSystCd())) {
                     moct = systStup.getClctNum();
+                    final long tmpStart = System.currentTimeMillis();
+                    collect.getLists().parallelStream()
+                            .forEach(clctDto -> {
+                                LinkClctMoctDto clctMoct = this.moctMap.get(clctDto.getLinkId());
+                                if (clctMoct != null) {
+                                    clctMoct.setSpeed(clctDto.getSpeed());
+                                    clctMoct.setValid(true);
+                                } else
+                                    this.moctMap.put(clctDto.getLinkId(), LinkClctMoctDto.builder()
+                                            .linkId(clctDto.getLinkId())
+                                            .speed(clctDto.getSpeed())
+                                            .valid(true)
+                                            .build());
+                            });
+                    log.info("[INF] {}", LogUtils.elapsedLog("SAVE MOCT MAP", moct, System.currentTimeMillis() - tmpStart));
                 }
                 if (LinkTrafCollectSetupService.PRIO.equals(collect.getClctSystCd())) {
                     pri = systStup.getClctNum();

+ 11 - 6
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafFusionService.java

@@ -7,6 +7,7 @@ import com.utic.center.utic.traf.server.config.TraceConfig;
 import com.utic.center.utic.traf.server.dto.LinkCollectDto;
 import com.utic.center.utic.traf.server.dto.LinkCollectResultDto;
 import com.utic.center.utic.traf.server.dto.LinkDto;
+import com.utic.center.utic.traf.server.dto.LinkTrafState;
 import com.utic.center.utic.traf.server.dto.dwdb.ParamAnalysisType;
 import com.utic.center.utic.traf.server.dto.utic.TrafficGrade;
 import lombok.Getter;
@@ -35,7 +36,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
     private LinkCollectResultDto collectMOCT;
 
     private void initialize() {
-        final long start = System.currentTimeMillis();
+//        final long start = System.currentTimeMillis();
 
         // 1. 수집된 소통정보를 객체로 초기화 한다.
         this.collectOPER = Optional.ofNullable(this.collectService.get(LinkTrafCollectSetupService.OPER))
@@ -48,6 +49,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
                 .orElseGet(() -> LinkCollectResultDto.builder().clctSystCd(LinkTrafCollectSetupService.MOCT).lists(new ArrayList<>()).build());
 
         this.linkService.getFusionInfo().init();
+        this.linkService.getFusionInfo().setLinkCnt(this.linkService.getLink1Count());
         this.linkService.getFusionInfo().setPrcsType(this.paramService.getAnalysisType().getAnalysisType());
         this.linkService.getFusionInfo().setColOprCnt(this.collectOPER.getLists().size());
         this.linkService.getFusionInfo().setColPriCnt(this.collectPRIO.getLists().size());
@@ -91,8 +93,11 @@ public class LinkTrafFusionService implements AbstractProcessService {
                 .forEach(link -> {
                     TrafficGrade grade = this.paramService.getTrafficGrade(link.getRoadRank());
                     totalCnt.incrementAndGet();
+                    int befSpeed = link.getTrafFsn().getSpeed();
                     if (link.fsnTrafficCorrect(grade)) {
-                        calCnt.incrementAndGet();
+                        if (befSpeed != link.getTrafFsn().getSpeed()) {
+                            calCnt.incrementAndGet();
+                        }
                     }
                 }
             );
@@ -130,7 +135,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
                             return;
                         }
                         calCnt.incrementAndGet();
-                        link.getTrafFsn().setTraffic(clctTraf);
+                        link.getTrafFsn().setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL, clctTraf);
                     });
         }
         this.linkService.getFusionInfo().setFsnPriCnt(calCnt.get());
@@ -155,7 +160,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
             }
             calPri.incrementAndGet();
 //            link.getTrafFsn().setTraffic("L00", dto.getSpeed(), "R", "L");
-            link.getTrafFsn().setTraffic(dto.getCenterId(), dto.getSpeed(), "R", "L");
+            link.getTrafFsn().setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL, dto.getCenterId(), dto.getSpeed(), "R", "L");
         });
 
         // 2. 우선순위(ETC) 수집 소통정보로 교통정보 생성
@@ -166,7 +171,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
             }
             calEtc.incrementAndGet();
 //            link.getTrafFsn().setTraffic("L00", dto.getSpeed(), "R", "L");
-            link.getTrafFsn().setTraffic(dto.getCenterId(), dto.getSpeed(), "R", "L");
+            link.getTrafFsn().setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL, dto.getCenterId(), dto.getSpeed(), "R", "L");
         });
 
         calCnt = calPri.get() + calEtc.get();
@@ -192,7 +197,7 @@ public class LinkTrafFusionService implements AbstractProcessService {
                 continue;
             }
             calCnt++;
-            link.getTrafFsn().setTraffic(dto);
+            link.getTrafFsn().setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL, dto);
         }
         this.linkService.getFusionInfo().setFsnOprCnt(calCnt);
         logInfo("운영자 소통정보 퓨전", totalCnt, calCnt, start);

+ 4 - 7
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafMissingService.java

@@ -84,8 +84,7 @@ public class LinkTrafMissingService implements AbstractProcessService {
 
             if (dto.getSpeed() > 0) {
                 TrafficGrade grade = this.paramService.getTrafficGrade(link.getRoadRank());
-                link.getTrafFsn().getState().setCrtDataType(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_MISSING);
-                link.getTrafFsn().setTraffic(dto.getCenterId(), dto.getSpeed(), dto.getMissValueYn(), dto.getDataResType());
+                link.getTrafFsn().setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_MISSING, dto.getCenterId(), dto.getSpeed(), dto.getMissValueYn(), dto.getDataResType());
                 link.fsnTrafficCorrect(grade);
                 calCnt.getAndIncrement();
             }
@@ -120,8 +119,7 @@ public class LinkTrafMissingService implements AbstractProcessService {
 
                     if (link.getTrafPtrn().getSpeed() > 0) {
                         TrafficGrade grade = this.paramService.getTrafficGrade(link.getRoadRank());
-                        link.getTrafFsn().getState().setCrtDataType(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_MISSING);
-                        link.getTrafFsn().setTraffic("C00", link.getTrafPtrn().getSpeed(), "T", "P");
+                        link.getTrafFsn().setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_MISSING, "C00", link.getTrafPtrn().getSpeed(), "T", "P");
                         link.fsnTrafficCorrect(grade);
                         calCnt.incrementAndGet();
                     }
@@ -151,8 +149,7 @@ public class LinkTrafMissingService implements AbstractProcessService {
                             totalCnt.incrementAndGet();
                             if (link.getMissPsd().getSpeed() > 0) {
                                 TrafficGrade grade = this.paramService.getTrafficGrade(link.getRoadRank());
-                                link.getTrafFsn().getState().setCrtDataType(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_MISSING);
-                                link.getTrafFsn().setTraffic("C00", link.getMissPsd().getSpeed(), link.getMissPsd().getMissValueYn(), "P");
+                                link.getTrafFsn().setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_MISSING, "C00", link.getMissPsd().getSpeed(), link.getMissPsd().getMissValueYn(), "P");
                                 link.fsnTrafficCorrect(grade);
                                 calCnt.incrementAndGet();
                             }
@@ -312,7 +309,7 @@ public class LinkTrafMissingService implements AbstractProcessService {
                     if (sumSpeed > 0. && sumLength > 0. && clctCnt > 0) {
                         TrafficGrade grade = this.paramService.getTrafficGrade(link.getRoadRank());
                         int speed = Math.round(sumSpeed / sumLength);
-                        link.getTrafFsn().setTraffic("C00", speed, "M", dataResType);
+                        link.getTrafFsn().setTraffic(LinkTrafState.TRAFFIC_CRT_DATA_TYPE.CRT_DATA_NORMAL, "C00", speed, "M", dataResType);
                         link.fsnTrafficCorrect(grade);
                         calCnt.incrementAndGet();
                     }

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

@@ -54,6 +54,7 @@ public class LinkTrafPrcsAfterService implements AbstractProcessService {
 
     private void initLinkTraf() {
         final long start = System.currentTimeMillis();
+        this.collectService.initCollectTraf();
         this.linkService.initLinkTraf();
         log.info("[INF] {}", LogUtils.elapsedLog("교통정보 메모리 초기화", System.currentTimeMillis() - start));
     }

+ 2 - 0
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveCacheService.java

@@ -33,8 +33,10 @@ public class LinkTrafSaveCacheService implements AbstractProcessService {
 
         long count = this.linkService.getLinkMap().values().parallelStream()
                 .filter(link -> link.getLinkLevel() == 1)
+                .filter(link -> link.getTrafFsn().getState().isState())
                 .filter(link -> link.getTrafFsn().getSpeed() == 0)
                 .count();
+        // 1레벨 링크 중, 소통상태이면서 속도가 0인 링크 개수
         this.linkService.getFusionInfo().setZeroSpdCnt((int)count);
 
         // 모든 링크에 대해 센터 소통정보 생성

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

@@ -26,6 +26,43 @@ public class LinkTrafSaveCenterService implements AbstractProcessService {
     @ProcessingElapsed(type="TRAFFIC", name="교통정보 CENTER 저장", starting = false)
     @Override
     public boolean processing() {
+        final String tableName = ApplicationRepository.TABLE_TRAFFIC_CENTER;
+        try {
+            // 1. 병렬 DML을 위한 세션 열기 (BATCH 모드 + 수동 커밋)
+            SqlSession sqlSession = this.sqlSessionFactory.openSession(ExecutorType.BATCH, false);
+            UticTrafficMapper mapper = sqlSession.getMapper(UticTrafficMapper.class);
+
+            // 4. 병렬 INSERT 수행
+            int insertCount = mapper.mergeTrafficCenter();
+            if (insertCount == -2147482646) {
+                log.info("[INS] {}", LogUtils.elapsedLog(tableName));
+            } else {
+                log.warn("[WAN] LinkTrafCenterService.run: {}: insert warning ({}).", tableName, insertCount);
+            }
+
+            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);
+            }
+
+            // 5. 트랜잭션 커밋
+            sqlSession.commit();    // 작업 데이터가 여기서 반영됨
+
+            // 6. 세션 종료
+            sqlSession.close();
+        }
+        catch (Exception e) {
+            log.error("[ERR] LinkTrafCenterService.processing: Error : {}", e.getMessage());
+            return false;
+        }
+        return true;
+    }
+
+//    @ProcessingElapsed(type="TRAFFIC", name="교통정보 CENTER 저장", starting = false)
+//    @Override
+    public boolean processingOld() {
         final String tableName = ApplicationRepository.TABLE_TRAFFIC_CENTER;
         try {
             // 1. 병렬 DML을 위한 세션 열기 (BATCH 모드 + 수동 커밋)

+ 23 - 8
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/LinkTrafSaveDwdbService.java

@@ -21,11 +21,13 @@ 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.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Data
@@ -37,9 +39,9 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
     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 final DwdbTrafficRepository dwdbRepo;
 
     private SqlSessionFactory sqlSessionFactory;
 
@@ -51,7 +53,6 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
 
     private void insertLinkFusionLog() {
         LinkTrafFusionInfo fusionInfo = this.linkService.getFusionInfo();
-        log.info("[INF] DWDB 교통정보 처리결과: {}", fusionInfo);
         this.dwdbRepo.insertLinkFusionLog(fusionInfo);
     }
 
@@ -120,9 +121,15 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
         final String jobTable = ApplicationRepository.TABLE_TRAFFIC_CENTER_HIST;
 
         // 모든 링크 레벨에 대하여 작업처리
+        // this.linkService.getLinkLists()
+        final List<String> linkList = this.linkService.getLinkMap().entrySet().stream()
+                .filter(entry -> entry.getValue().getTrafFsn().getState().isState())
+                .filter(entry -> entry.getValue().getTrafFsn().getSpeed() > 0)
+                .map(Map.Entry::getKey)
+                .collect(Collectors.toList());
         final ConcurrentHashMap<Integer, DbmsBatchJobResult> mapData = new ConcurrentHashMap<>();
         final int prcsThreadCount = ApplicationRepository.PRCS_THREAD_COUNT;
-        final int threadPoolSize = WorkerUtils.allocateWorkerLinkJobs(mapData, prcsThreadCount, this.linkService.getLinkLists());
+        final int threadPoolSize = WorkerUtils.allocateWorkerLinkJobs(mapData, prcsThreadCount, linkList);
         final ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
 
         mapData.forEach((key, dbmsJobResult) -> {
@@ -162,7 +169,7 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
         log.info("[INF] {}", LogUtils.elapsedLog(jobTable, resultCount, totalTime));
     }
 
-    private void batchLinkMissingValueHist(SqlSessionFactory sqlSessionFactory, DbmsBatchJobResult dbmsJobResult, LinkService linkRepo, String jobTable) {
+    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;
@@ -173,12 +180,11 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
         try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
             DwdbTrafficMapper mapper = sqlSession.getMapper(DwdbTrafficMapper.class);
             for (String linkId : dbmsJobResult.getLinkIds()) {
-                LinkDto link = linkRepo.getLinkMap().get(linkId);
+                LinkDto link = linkService.getLinkMap().get(linkId);
                 if (link == null) {
                     continue;
                 }
-
-                LinkMissingValueHistDto valueHist = linkRepo.getMissingValueHist(link, exeDate);
+                LinkMissingValueHistDto valueHist = linkService.getMissingValueHist(link, exeDate);
                 if (valueHist == null) {
                     continue;
                 }
@@ -219,9 +225,18 @@ public class LinkTrafSaveDwdbService implements AbstractProcessService {
         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 ConcurrentHashMap<Integer, DbmsBatchJobResult> mapData = new ConcurrentHashMap<>();
         final int prcsThreadCount = 4;
-        final int threadPoolSize = WorkerUtils.allocateWorkerLinkJobs(mapData, prcsThreadCount, this.linkService.getLink1Lists());
+        final int threadPoolSize = WorkerUtils.allocateWorkerLinkJobs(mapData, prcsThreadCount, level1LinkList);
         final ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
 
         mapData.forEach((key, dbmsJobResult) -> {

+ 16 - 12
utic-traf-server/src/main/java/com/utic/center/utic/traf/server/service/worker/LinkTrafCollectWorker.java

@@ -2,7 +2,6 @@ package com.utic.center.utic.traf.server.service.worker;
 
 import com.utic.center.common.spring.SpringUtils;
 import com.utic.center.common.utils.LogUtils;
-import com.utic.center.common.utils.TimeUtils;
 import com.utic.center.utic.traf.server.dto.LinkCollectDto;
 import com.utic.center.utic.traf.server.dto.LinkCollectParam;
 import com.utic.center.utic.traf.server.dto.LinkCollectResultDto;
@@ -16,7 +15,9 @@ import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 @Slf4j
@@ -50,6 +51,7 @@ public class LinkTrafCollectWorker implements Runnable {
 
         int resultCount = 0;
         List<LinkCollectDto> result = new ArrayList<>();
+        List<LinkCollectDto> queryResult = new ArrayList<>();
         try {
             String queryId = "findAllLinkTraf" + clctSystCd;
             MappedStatement mappedStatement = sqlSessionFactory.getConfiguration().getMappedStatement(queryId);
@@ -63,7 +65,7 @@ public class LinkTrafCollectWorker implements Runnable {
             SqlSession sqlSession = null;
             try {
                 sqlSession = sqlSessionFactory.openSession(ExecutorType.SIMPLE, false);
-                result = sqlSession.selectList(queryId, params);
+                queryResult = sqlSession.selectList(queryId, params);
             } catch (Exception e) {
                 log.error("[ERR] LinkTrafCollectWorker.run: Exception: [{}], {}, {}, {}", this.clctSystCd, jobName, queryId, e.getMessage());
             }
@@ -73,20 +75,20 @@ public class LinkTrafCollectWorker implements Runnable {
                 }
             }
 
-            if (result == null) {
+            if (queryResult == null) {
                 this.mapData.put(this.clctSystCd, LinkCollectResultDto.builder().clctSystCd(this.clctSystCd).lists(new ArrayList<>()).build());
             }
             else {
-                resultCount = result.size();
+                resultCount = queryResult.size();
 
                 // 수집의 경우 LinkId 가 중복될 수 있으므로
                 // 중복된 LinkId 를 제거하기 위해 HashSet 을 사용하여 중복값을 제거
-//                Set<String> uniqueSet = new HashSet<>();
-//                for (LinkCollectDto dto : queryResult) {
-//                    if (uniqueSet.add(dto.getLinkId())) {  // HashSet 의 add() 메서드는 중복값이 있으면 false 를 반환
-//                        result.add(dto);
-//                    }
-//                }
+                Set<String> uniqueSet = new HashSet<>();
+                for (LinkCollectDto dto : queryResult) {
+                    if (uniqueSet.add(dto.getLinkId())) {  // HashSet 의 add() 메서드는 중복값이 있으면 false 를 반환
+                        result.add(dto);
+                    }
+                }
                 this.mapData.put(this.clctSystCd, LinkCollectResultDto.builder().clctSystCd(this.clctSystCd).lists(result).build());
             }
         } catch (Exception e) {
@@ -94,8 +96,10 @@ public class LinkTrafCollectWorker implements Runnable {
             this.mapData.put(this.clctSystCd, LinkCollectResultDto.builder().clctSystCd(this.clctSystCd).lists(new ArrayList<>()).build());
         }
 
-        log.info("[INF] {} | {}", LogUtils.elapsedLog(jobName, resultCount, System.currentTimeMillis() - start), Thread.currentThread().getName());
-        TimeUtils.sleep(10); // 10ms 대기
+        log.info("[INF] {}: SET: {} EA. | {}",
+                LogUtils.elapsedLog(jobName, resultCount, System.currentTimeMillis() - start),
+                LogUtils.numberLog(result.size()),
+                Thread.currentThread().getName());
     }
 
 }

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

@@ -16,11 +16,13 @@ import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
 
+import java.util.List;
 import java.util.Map;
 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
 @RequiredArgsConstructor
@@ -41,9 +43,16 @@ public class LinkTrafSaveCacheWorker implements Runnable {
             return;
         }
 
-        int prcsThreadCount = ApplicationRepository.PRCS_THREAD_COUNT;
-        int threadPoolSize = WorkerUtils.allocateWorkerLinkJobs(mapData, prcsThreadCount, this.linkService.getLinkLists());
-        ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
+        // this.linkService.getLinkLists()
+        final List<String> linkList = this.linkService.getLinkMap().entrySet().stream()
+                .filter(entry -> entry.getValue().getTrafFsn().getState().isState())
+                .filter(entry -> entry.getValue().getTrafFsn().getSpeed() > 0)
+                .map(Map.Entry::getKey)
+                .collect(Collectors.toList());
+
+        final int prcsThreadCount = ApplicationRepository.PRCS_THREAD_COUNT;
+        final int threadPoolSize = WorkerUtils.allocateWorkerLinkJobs(mapData, prcsThreadCount, linkList);
+        final ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
 
         mapData.forEach((key, dbmsJobResult) -> {
             executorService.execute(() -> processBatch(sqlSessionFactory, dbmsJobResult, this.linkService, jobTable));

+ 3 - 3
utic-traf-server/src/main/resources/mybatis/mapper/utic/LinkMapper.xml

@@ -39,7 +39,7 @@
 
     <resultMap id="result-logicalLink" type="com.utic.center.utic.traf.server.dto.LogicalLinkDto">
         <id column="logicalLinkId" property="logicalLinkId"/>
-        <collection column="IFSC_ID" property="linkIds" ofType="java.lang.String" javaType="java.util.ArrayList">
+        <collection property="linkIds" ofType="java.lang.String" javaType="java.util.ArrayList">
             <result column="linkId"/>
         </collection>
     </resultMap>
@@ -48,14 +48,14 @@
         <![CDATA[
         SELECT LOL.LOGICALLINKID AS logicalLinkId, LOL.SEQUENCE AS linkSeq, LOL.LINKID AS linkId
         FROM LOGICALLINK LOL,
-             (SELECT LINKID, LINKLEVEL
+             (SELECT LINKID AS LOGICALLINKID, LINKLEVEL
               FROM LINK
               WHERE LINKLEVEL = #{linkLevel}) LVL,
              (SELECT LINKID
               FROM LINK
               WHERE LINKLEVEL = '1') LNK
         WHERE LOL.LINKLEVEL = '1'
-          AND LOL.LOGICALLINKID = LVL.LINKID
+          AND LOL.LOGICALLINKID = LVL.LOGICALLINKID
           AND LOL.LINKID = LNK.LINKID
         ORDER BY LOL.LOGICALLINKID, LOL.SEQUENCE
         ]]>

+ 50 - 3
utic-traf-server/src/main/resources/mybatis/mapper/utic/UticTrafficMapper.xml

@@ -36,7 +36,7 @@
 
     <insert id="insertTrafficCenterCache" parameterType="com.utic.center.utic.traf.server.dto.LinkTrafCenterDto">
         <![CDATA[
-        INSERT /*+ APPEND PARALLEL(TRAFFIC_CENTER_CACHE, 2) */ INTO TRAFFIC_CENTER_CACHE NOLOGGING (
+        INSERT /*+ APPEND PARALLEL(TRAFFIC_CENTER_CACHE, 6) */ INTO TRAFFIC_CENTER_CACHE NOLOGGING (
             LINKID,
             MISSVALUEYN,
             REGDATE,
@@ -67,13 +67,13 @@
 
     <delete id="deleteTrafficCenter">
         <![CDATA[
-        DELETE /*+ PARALLEL(TMP_TRAFFIC_CENTER, 6) */ FROM TMP_TRAFFIC_CENTER
+        DELETE /*+ PARALLEL(TMP_TRAFFIC_CENTER, 8) */ FROM TMP_TRAFFIC_CENTER
         ]]>
     </delete>
 
     <insert id="insertTrafficCenter">
         <![CDATA[
-        INSERT /*+ APPEND PARALLEL(TMP_TRAFFIC_CENTER, 3) */ INTO TMP_TRAFFIC_CENTER NOLOGGING (
+        INSERT /*+ APPEND PARALLEL(TMP_TRAFFIC_CENTER, 6) */ INTO TMP_TRAFFIC_CENTER NOLOGGING (
             LINKID,
             MISSVALUEYN,
             REGDATE,
@@ -97,4 +97,51 @@
         ]]>
     </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>

+ 38 - 1
utic-traf-server/src/main/resources/mybatis/mapper/utic/collect/LinkCollectMoct.xml

@@ -4,6 +4,43 @@
 <mapper namespace="com.utic.center.utic.traf.server.dao.mapper.utic.LinkCollectMoctMapper">
 
     <select id="findAllLinkTrafMOCT" resultType="com.utic.center.utic.traf.server.dto.LinkCollectDto" parameterType="com.utic.center.utic.traf.server.dto.LinkCollectParam" fetchSize="1000">
+        <![CDATA[
+        SELECT A.STD_LINK_ID AS linkId,
+               1             AS crtPriority,
+               'R'           AS missValueYn,
+               'S'           AS dataResType,
+               'C00'         AS centerId,
+               A.SPEED       AS speed
+        FROM (
+                 SELECT STD_LINK_ID, SPEED, REG_DATE
+                 FROM CURLINKST_MOCT_PRIVATE_LOG@PTDBSDB
+                 WHERE REG_DATE >= TO_CHAR(SYSDATE - INTERVAL '6' MINUTE, 'YYYYMMDDHH24MISS')
+                   AND SPEED BETWEEN 1 AND 149
+             ) A
+                 JOIN LINK B ON A.STD_LINK_ID = B.LINKID
+        WHERE B.LINKLEVEL = '1'
+        ORDER BY A.STD_LINK_ID, A.REG_DATE ASC
+        ]]>
+    </select>
+
+    <select id="findAllLinkTrafMOCTx" resultType="com.utic.center.utic.traf.server.dto.LinkCollectDto" parameterType="com.utic.center.utic.traf.server.dto.LinkCollectParam" fetchSize="1000">
+        <![CDATA[
+        SELECT A.STD_LINK_ID AS linkId,
+               1             AS crtPriority,
+               'R'           AS missValueYn,
+               'S'           AS dataResType,
+               'C00'         AS centerId,
+               A.SPEED       AS speed
+        FROM CURLINKST_MOCT_PRIVATE_LOG@PTDBSDB A, LINK B
+        WHERE A.REG_DATE >= TO_CHAR(SYSDATE - INTERVAL '6' MINUTE, 'YYYYMMDDHH24MISS')
+          AND A.STD_LINK_ID = B.LINKID
+          AND B.LINKLEVEL = '1'
+          AND A.SPEED BETWEEN 1 AND 149
+        ORDER BY A.STD_LINK_ID, A.REG_DATE ASC
+        ]]>
+    </select>
+
+    <select id="findAllLinkTrafMOCTxxx" resultType="com.utic.center.utic.traf.server.dto.LinkCollectDto" parameterType="com.utic.center.utic.traf.server.dto.LinkCollectParam" fetchSize="1000">
         <![CDATA[
         SELECT
             T.STD_LINK_ID AS linkId,
@@ -17,7 +54,7 @@
                      T.STD_LINK_ID,
                      MAX(T.REG_DATE) AS MAX_REGDATE
                  FROM CURLINKST_MOCT_PRIVATE_LOG@PTDBSDB T
-           INNER JOIN LINK@PTDBSDB C
+           INNER JOIN LINK C
                    ON T.STD_LINK_ID = C.LINKID
                 WHERE C.LINKLEVEL = '1'
                   AND T.REG_DATE >= TO_CHAR(SYSDATE - INTERVAL '6' MINUTE, 'YYYYMMDDHH24MISS')