들어가며
예치금을 다루는 시스템에서 금액의 오차는 작더라도 그냥 넘길 수 없습니다.
그런데 금액이 틀렸다는 사실을 아는 것과, 왜 틀렸는지를 아는 것은 전혀 다른 문제였습니다.
이번 글에서는 하루치 합계를 비교하던 예치금 정합성 배치를, 주문 1건의 기대값에서 출발하는 구조로 바꾼 과정을 이야기합니다.
기존 구조: 하루치 합계를 비교하는 양식
예치금의 정합성을 보여주는 템플릿이 있습니다. 핵심은 다음 한 줄로 정리됩니다.
오늘자 거래 집계 금액 = 오늘과 어제 사이의 거래금액 차이 결제금액, 수수료 등 여러 항목의 하루치 데이터를 집계하고, 그 합을 비교해 오차를 확인하는 방식이었습니다.
문제: 오차는 보이는데 원인은 보이지 않는다
이 구조에는 두 가지 문제가 있었습니다.
1. 계산이 오래 걸렸습니다
하루치 거래금액, 즉 오늘까지의 거래금액과 어제까지의 거래금액의 차이를 각각 계산하기 위해 DB 전체를 뒤져야 했습니다.
2. 오차의 원인을 추적하기 어려웠습니다
오늘자 거래 합계만으로는 어떤 주문에 문제가 있는지 알 수 없었습니다.
- 주문 1건이 잘못된 것인지
- 여러 건이 잘못되어 그 합으로 오차가 발생한 것인지
- 서로 다른 항목의 이슈가 상쇄되어 드러나지 않은 것은 없는지
합계는 이상 여부를 확인하는 데는 유용합니다. 하지만 합산 과정에서 건별 정보가 사라지기 때문에, 원인을 찾는 데는 도움이 되지 않았습니다.
오차 하나를 찾아내는 데 꼬박 하루가 걸리기도 했습니다.
전환점: 주문이 단 1건뿐이라면?
일단 하나씩, 거래 집계부터 풀어보기로 했습니다. 출발점은 단순한 질문이었습니다.
여러 주문이 아니라 주문이 1건만 있다면, 템플릿에는 어떻게 보여야 할까?
이 질문이 곧 답이었습니다. 주문 1건, 거래상태 1건마다 템플릿에 나타나야 할 값은 정해져 있기 때문입니다.
- 주문 1건, 거래상태 1건에 대한 기대값을 정의
- 기대값을 규칙으로 만들어 배치에 적용
- 규칙을 통과하지 못한 건을 점검하고 수정
이렇게 검증을 통과한 건들이 쌓이면, 하루치 거래 합계도 신뢰할 수 있는 값이 됩니다.
합계를 먼저 보고 원인을 거슬러 찾던 흐름이, 건별로 검증한 값을 쌓아 신뢰할 수 있는 합계를 만드는 흐름으로 바뀌었습니다.
정산에 의미 있는 상태만 남기기
주문상태별로 규칙을 만들다 보니 발견한 사실이 있습니다.
주문상태 중에는 Hold처럼 정산 관점에서 의미가 없는 상태도 있었습니다.
이런 상태는 과감히 제외하고, 정산에 의미 있는 상태만 남겼습니다.
중복을 막는 거래상태별 기준일 테이블
의미 있는 상태만 골라도 문제는 남아 있었습니다.
지금 계산하는 상태가 어쩌면 중복일지도 모릅니다. 과거 데이터를 다시 조회해 동일한 상태가 또 있는지 확인하고, 있으면 이번 계산에서 제외해야 했습니다.
이 문제는 별도의 테이블을 만들어 해결했습니다.
- 주문번호별로 거래상태의 날짜를 정의
- 집계는 이 테이블에 적힌 날짜를 기준으로 수행
- 중복 내역이 들어와도 기준 날짜는 변경되지 않음
같은 내역이 몇 번 들어오더라도 집계 결과는 달라지지 않습니다.
필요한 거래상태만, 정확한 날짜로 정의하니 조회 범위도 줄었고 실행 시간도 크게 단축되었습니다.
3개의 검증축
신뢰할 수 있는 거래 합계가 생기자, 이 값을 기준으로 삼을 수 있었습니다.
거래 합계를 바탕으로 거래외 데이터를 계산하고, 이를 하루치 거래금액과 비교합니다.
이렇게 세 개의 검증축이 완성되었습니다.
- 거래: 건별 규칙을 통과한 값을 쌓은 합계
- 거래외: 거래 합계를 기준으로 계산한 거래외 데이터
- 전체 거래금액: 위 값들과 대조하는 하루치 거래금액
Rule을 쌓아 만든 정합성 체크 툴
신뢰할 수 있는 값이 갖춰지자, 그 위에 필요한 Rule을 하나씩 정의할 수 있었습니다.
예를 들면 다음과 같은 규칙입니다.
구매자의 예치금 사용액 + 판매자의 정산금 + 거래외 예치금 변동 = 회원 전체의 예치금 변동액 필요한 규칙을 채워 넣고, 어긋나는 값은 표시합니다.
여기에 집계 결과를 보기 좋게 배치하면, 예치금 정합성을 한눈에 확인할 수 있는 체크 툴이 완성됩니다.
마치며
정합성 구조를 바꾸며 얻은 가장 큰 교훈은, 합계의 신뢰도는 그 합계를 이루는 가장 작은 단위에서 나온다는 점입니다.
오차가 발생했을 때 DB 전체를 뒤지는 대신, 규칙을 통과하지 못한 건부터 살펴보면 됩니다.
복잡해 보이던 문제도 “주문이 1건뿐이라면?”이라는 간단한 질문으로 풀리기 시작했습니다.

