피드로 돌아가기
Dev.toBackend
원문 읽기
DB Unique Constraint와 Outbox 패턴을 통한 중복 입금 0건 달성
I Thought I'd Just Call a Blockchain API. It Didn't Work Out That Way.
AI 요약
Context
FastAPI, PostgreSQL, Redis 기반의 결제 시스템에서 At-least-once delivery 특성으로 인한 중복 처리 및 Race Condition 발생. Redis 분산 락의 원자성 부족과 Celery의 기본 Ack 설정으로 인한 데이터 유실 및 정밀도 손실이 시스템 신뢰성을 저해한 상황.
Technical Solution
- Redis 분산 락 대신 PostgreSQL Unique Constraint를 적용하여 Redis-DB 간 원자성 결여로 인한 중복 처리 원천 차단
- SELECT FOR UPDATE NOWAIT 기반의 비관적 락을 도입하여 잔액 확인과 차감 사이의 TOCTOU Race Condition 해결
- Celery의 acks_late 설정 및 Transactional Outbox 패턴을 결합하여 프로세스 종료 시의 이벤트 유실 방지 및 보장된 전달 구현
- JSON Float 직렬화로 인한 정밀도 손실 방지를 위해 Decimal 타입 처리 및 엄격한 데이터 타입 관리 적용
- 상태 전이 제어를 위해 FSM(Finite State Machine) 기반의 VALID_TRANSITIONS 로직을 도입하여 비정상적인 상태 변경 차단
- PgBouncer Transaction Pooling 도입 시 세션 수준의 Isolation Level 유실 문제를 BEGIN ISOLATION LEVEL 구문으로 해결
실천 포인트
1. 외부 API의 At-least-once delivery를 전제한 Idempotency Key 설계 여부 확인
2. 분산 락 사용 시 락 획득과 DB 트랜잭션 사이의 Crash Scenario 검토
3. Celery 사용 시 acks_late 설정과 Outbox 패턴을 통한 메시지 유실 방지책 적용
4. 금융 데이터 처리 시 JSON Float 직렬화로 인한 정밀도 손실 가능성 점검
5. PgBouncer Transaction Pooling 사용 시 Session-level 설정의 유효성 검증