포인트 정산을 위한 마이그레이션 + FIFO 차감 전략

Choi Wang Gyu·2025년 5월 22일

✅ 문제 상황: 포인트 만료 및 사용 내역 정산 문제

현재 운영 중인 시스템에서는 포인트 지급/사용 기록은 point_tx 테이블에 남고, 유저의 총 보유 포인트는 user_point에 관리되고 있었다. 그러나 다음과 같은 문제가 있었다

📌 문제

  • GRANT(지급)된 개별 포인트가 얼마나 사용됐는지 알 수 없음
  • USE(사용) 기록은 남지만 어떤 지급건에서 사용됐는지는 추적 불가
  • 지급된 포인트는 1년 후 만료되어야 하는 정책이 있음
  • 유저에게 지급된 바우처성 포인트나 결제포인트를 오래된 순서로 차감하고 싶었지만 이를 위한 정보가 없었음
    → 결국 남은 포인트(remaining_point)를 파악할 수 없어, 정합성 있는 만료/차감 로직을 구현할 수 없는 상황이었다.

✅ 해결 방법: 마이그레이션 기반 정산 + FIFO 차감 로직 구축

1. 마이그레이션 설계 – 남은 포인트 추적 및 정합성 확보

  • 기존 point_tx 테이블을 순회하여 FIFO 원칙에 따라 GRANT → USE 매핑을 구성
  • 각 GRANT 트랜잭션에 대해 남은 포인트(remaining_point)를 계산하여 저장
  • USE 트랜잭션에 대해 어떤 GRANT에서 차감되었는지 기록하는 point_use_detail 테이블 구성

2. 차감 로직 설계 – FIFO 기반처리

  • 지급 시: remaining_point = point로 초기화
  • 사용 시:
    1. 새로운 USE 트랜잭션을 기록하고
    2. remaining_point > 0인 GRANT를 createdAt ASC 순서로 조회
    3. FIFO 방식으로 순차 차감 및 point_use_detail에 기록
단계처리 내용
1️⃣포인트가 충분한지 (GRANT.remaining_point 총합으로) 사전 검증
2️⃣point_txUSE 트랜잭션 저장
3️⃣GRANT 트랜잭션들을 createdAt ASC 정렬하여 FIFO 방식으로 차감
4️⃣GRANTremaining_point를 더티 체킹 방식으로 업데이트 (saveAll 없이도 반영됨)
5️⃣point_use_detail 테이블에 차감 내역 기록 (어떤 GRANT에서 얼마를 썼는지 추적 가능)
예시
순번타입포인트남은 포인트설명
1GRANT10000다 써버림
2GRANT500300200원만 썼음
3USE-1200-총 1200원 사용

진행과정 순서

  1. 포인트 기록과 유저 포인트 덤프 추출
  2. 마이그레이션 설계(로직생성)
  3. 정합성 체크: point_tx.remaining_point 합과 유저 현재 포인트 비교
  4. 1명 유저로 선행 테스트
  5. 차감 로직변경

구현

1. 스키마 설계 요약 (SQL 예시)

  • remaining_point 컬럼을 추가하여 지급된 포인트의 남은 양을 저장합니다.
  • 마이그레이션 이전에 기존 GRANT 트랜잭션의 포인트 값을 초기값으로 세팅합니다.
  • 실패 이력 및 포인트 차감 상세 기록을 위한 테이블도 정의합니다.

2. 마이그레이션 처리 흐름 (1회성 처리)

  • 유저의 포인트 트랜잭션을 createdAt ASC로 정렬하여 불러옵니다.
  • GRANT 트랜잭션은 큐에 저장하고, USE 트랜잭션이 나올 때마다 큐를 기준으로 FIFO 순서대로 차감합니다.
  • 어떤 GRANT에서 얼마만큼 차감되었는지를 기록하고, 사용 후 남은 GRANT의 포인트는 업데이트합니다.
  • 차감 도중 부족할 경우 실패 이력으로 기록합니다.

3. 포인트 사용 시 차감 처리 흐름 (요청 시점 처리)

  • 사용자가 포인트를 사용할 때, 해당 유저의 GRANT 트랜잭션 중 remaining_point > 0인 항목을 정렬하여 조회합니다.
  • FIFO 순으로 남은 포인트를 차감하고, remaining_point 값을 갱신합니다.
  • 각 차감 항목은 point_use_detail에 기록됩니다.
  • 차감할 수 있는 포인트가 부족할 경우 예외를 발생시킵니다.

📝 요약 정리

  • 총 포인트만 관리하던 구조라, 지급(GRANT)과 사용(USE) 간의 흐름 정합성이 보장되지 않았다.
  • 마이그레이션으로 remaining_point 및 차감 매핑 정보 구성
  • 차감 시에도 FIFO 원칙, 더티 체킹, use_detail 저장으로 정산 정확도 확보
  • 지급된 포인트가 언제, 어디서, 얼마만큼 사용되었는지를 정밀하게 추적 가능해짐

💡 보완 사항 및 고려점

병렬 처리가 성능 향상에 기여할 수 있으나, FIFO(시간 순서 보장)가 핵심이므로 제외함
포인트 만료 로직은 batch 스케줄링이나 scheduled task로도 확장 가능

참고로 테이블명이나 컬럼명은 사내와 동일하지않습니다 ai가 생성된 예시입니다

0개의 댓글