트랜잭션·데이터 정합성 · Data Modeling

변경되는 업무 데이터를 일관되게 집계하는 방법: 재집계·휴일·시간대 처리

완료·재반응·휴일 정보가 뒤늦게 바뀌는 업무에서 전일 집계만으로는 과거 지표를 고칠 수 없어, 최근 14일을 반복 재집계하도록 설계한 과정입니다.

Spring BatchData ConsistencyTime ZoneIdempotencyKPI

집계가 끝났다는 판단부터 다시 봤다

일별 KPI는 보통 하루가 지나면 확정된다고 생각하기 쉽다. 그래서 가장 단순한 배치는 전날인 D-1의 원천 데이터를 읽어 집계 테이블에 저장한다. 원천 데이터가 이후 바뀌지 않는다면 이 방식으로 충분하다.

하지만 실험·생산 업무의 완료 건수, 장비 가동률, 재반응률과 재합성률은 발생 시점에 모두 확정되지 않았다. 처리가 다음 날 완료될 수 있고, 사후에 상태나 제외 조건이 정정될 수 있으며, 공휴일 등록도 집계 이후 보완될 수 있었다. 이때 전일 데이터만 새로 계산하면 이미 저장된 과거 KPI는 잘못된 값으로 남는다.

문제는 Query 한 개의 정확성이 아니라 변경 가능한 업무 사실을 언제까지 다시 계산할 것인가였다.

늦게 도착하는 데이터가 만드는 불일치

대시보드에는 Web 조회와 별도로 CES·Oligo 지표를 만드는 Batch가 있었다. 두 영역이 같은 숫자를 보여주려면 최소한 다음 기준이 일치해야 했다.

  • 완료 건수와 비율을 계산할 기준 시점
  • 재반응·재합성으로 분류할 상태와 제외 조건
  • 장비 가동률에서 휴일을 제외하는 규칙
  • UTC로 저장된 운영 데이터와 법인별 현지 날짜의 경계
  • 이미 집계한 날짜의 원천 데이터가 바뀌었을 때의 재처리 범위

예를 들어 월요일에 금요일 작업의 상태가 보완되면, 월요일 배치가 일요일만 계산해서는 금요일 지표를 고칠 수 없다. 휴일이 뒤늦게 등록돼도 같은 문제가 생긴다. 화면이 원천 테이블을 직접 조회하는 구간과 집계 테이블을 조회하는 구간이 섞여 있다면 사용자에게 서로 다른 숫자가 보일 수도 있다.

검토한 재처리 범위

재집계 범위는 넓을수록 정합성에 유리하지만 매일 읽고 다시 계산할 데이터도 늘어난다.

검토한 재처리 범위 데이터 표
방식장점남는 문제
D-1만 집계처리 범위가 가장 작음이틀 이상 지난 데이터의 사후 변경을 반영하지 못함
전체 기간 재집계모든 과거 변경을 반영 가능매일 전체 원천 데이터를 다시 읽는 비용이 큼
변경 이벤트 기반 재집계변경된 대상만 계산 가능여러 레거시 업무 경로가 빠짐없이 이벤트를 발행해야 함
최근 구간 반복 재집계비용을 제한하면서 일반적인 사후 변경을 흡수윈도 밖의 변경은 별도 재처리가 필요

운영 데이터의 변경 패턴과 일 배치 범위를 함께 고려해 D-14~D-1을 다시 계산하는 방식을 적용했다. 오늘 진행 중인 데이터는 제외하고, 최근 14일의 완료·재반응·합성 지표를 반복 계산해 사후 변경을 흡수하는 구조다.

재집계를 안전하게 만드는 처리 단위

같은 날짜를 여러 번 계산하려면 실행 횟수만큼 결과가 누적되지 않아야 한다. 그래서 날짜와 지표를 논리적인 재처리 단위로 보고, 같은 구간을 다시 실행해도 최종 결과가 한 번 실행한 것과 같도록 구성했다.

공개용으로 단순화하면 배치 흐름은 다음과 같다.

아래 코드는 문제 해결 구조를 설명하기 위한 pseudocode이며 실제 클래스·테이블·설정 이름과는 무관합니다.

businessToday = 현재 시각을 법인 표준 시간대의 날짜로 변환

for targetDate in businessToday - 14일 ... businessToday - 1일:
    source = targetDate의 원천 업무 데이터 조회
    holiday = targetDate의 휴일 여부 조회
    metrics = 동일한 완료·제외·비율 규칙으로 계산
    targetDate의 기존 집계 결과를 metrics로 교체
    실행 결과와 처리 구간 기록

핵심은 반복문의 모양이 아니라 다음 책임을 분리한 점이었다.

  • 업무 날짜 결정: 서버 날짜가 아니라 법인별 시간대 기준
  • 원천 데이터 판정: 완료·재반응·재합성의 공통 규칙
  • 휴일 판정: 장비 가동률 계산과 휴일 관리 데이터 연결
  • 재처리: 동일 날짜를 다시 계산해도 중복되지 않는 저장
  • 운영 추적: 어느 구간이 언제 다시 계산됐는지 확인할 Batch 이력

UTC 저장과 현지 날짜를 섞지 않았다

운영 DB의 시각은 UTC 기준으로 저장됐지만 대시보드의 “하루”는 사용 법인의 현지 날짜였다. 서버의 SYSDATE나 기본 시간대로 날짜를 자르면 자정 부근 데이터가 전날 또는 다음 날 지표에 들어갈 수 있다.

Web과 Batch에서 모두 활성 법인의 표준 시간대를 기준으로 현재 날짜와 조회 구간을 계산했다. 시간대 변환은 화면 표시 단계에만 두지 않고, 어떤 데이터가 어느 업무 날짜에 속하는지를 결정하는 집계 경계에도 적용했다.

휴일도 단순한 화면 표시 정보가 아니었다. 휴일 등록 전후로 장비 가동률의 분모와 집계 대상이 달라질 수 있으므로, 휴일 관리와 Batch의 제외 조건을 같은 규칙으로 연결했다.

검증은 숫자 한 번 맞추기로 끝내지 않았다

재집계 로직은 다음 조건을 나눠 확인했다.

  1. CES·Oligo의 일별 집계 결과를 같은 기간의 원천 데이터와 대조
  2. 이미 집계된 최근 날짜의 상태를 변경한 뒤 D-14~D-1 재실행 결과 확인
  3. 휴일 등록 전후 장비 가동률의 제외 조건 확인
  4. 법인 시간대 기준 날짜와 UTC 저장 시각의 경계 데이터 확인
  5. 같은 날짜를 반복 실행해도 집계 행이 중복되지 않는지 확인

차트가 정상적으로 그려지는지는 마지막 검증이었다. 먼저 Batch가 업무 규칙에 맞는 결과를 만들고, 그 결과를 Web 조회와 상세 화면이 같은 의미로 사용하는지를 확인했다.

이 방식의 한계

14일은 모든 과거 변경을 자동으로 복구한다는 뜻이 아니다. D-14보다 오래된 데이터가 수정되면 기간을 지정해 다시 집계하거나 별도의 운영 처리가 필요하다. 이 사례에는 재집계 전후의 정량적인 오류 감소율이나 처리시간 지표도 남아 있지 않으므로 그런 성과를 추가하지 않았다.

대신 운영 구조의 변화는 명확했다. 전일 데이터가 영원히 확정됐다고 가정하던 배치에서, 업무 데이터는 사후에 바뀔 수 있고 집계에는 명시적인 정정 가능 기간이 필요하다는 모델로 전환했다. KPI의 신뢰성은 계산식만이 아니라 시간대, 휴일, 재처리 범위와 멱등성을 함께 설계할 때 확보할 수 있다.