멱등성 상황
I’m happy to translate the article for you, but I don’t have the ability to retrieve the full text from the link you provided. Could you please paste the content you’d like translated (excluding any code blocks or URLs you want to keep unchanged)? Once I have the text, I’ll translate it into Korean while preserving the original formatting and markdown.
데이터베이스 트랜잭션을 이용한 신뢰할 수 있는 금전 이체 보장
PhonePe, Google Pay, 또는 Paytm과 유사한 디지털 지갑 시스템에서 사용자는 자신의 금액이 정확하고 안전하게 처리되기를 기대합니다. 한 계좌에서 금액이 차감되었지만 다른 계좌에 입금되지 않는 등 작은 불일치라도 심각한 재정 문제를 초래할 수 있습니다. 이러한 문제를 방지하기 위해 데이터베이스 시스템은 ACID properties, 특히 Durability에 의존하여 안전하고 일관된 트랜잭션을 보장합니다.
시스템 개요
시스템은 각 사용자가 잔액을 가지고 있는 accounts 테이블을 유지합니다. 사용자는 다음을 할 수 있습니다:
- 지갑에 돈을 저장하기
- 다른 사용자에게 돈을 이체하기
- 거래 내역을 보기
정확성을 보장하기 위해 데이터베이스는 음수 잔액 금지 및 타임스탬프 추적과 같은 규칙을 적용합니다.
안전한 이체 수행
일반적인 두 사용자 간의 금전 이체(예: Alice에서 Bob으로)는 트랜잭션 내에서 실행됩니다:
- 시스템이 트랜잭션을 시작합니다.
- 송신자의 계좌에서 금액을 차감합니다.
- 동일한 금액을 수신자의 계좌에 추가합니다.
- 트랜잭션을 커밋합니다.
모든 단계가 성공하면 트랜잭션이 영구적으로 저장됩니다. 커밋 후 데이터베이스를 조회하면 업데이트된 잔액이 올바르게 표시됩니다.
시스템 장애가 발생하면 어떻게 되나요?
커밋 전 장애
시스템이 트랜잭션이 커밋되기 전에 충돌하면, 변경 사항이 전혀 저장되지 않습니다. 데이터베이스는 트랜잭션을 자동으로 롤백하여 부분적인 업데이트가 발생하지 않도록 합니다. 이는 돈이 차감되었지만 입금되지 않는 상황을 방지합니다.
커밋 후 장애
시스템이 커밋 직후에 충돌하면, 변경 사항은 지속됩니다. 데이터베이스가 재시작될 때, 업데이트된 잔액은 그대로 유지됩니다. 이 동작은 Durability(지속성)를 보여주며, 트랜잭션이 커밋되면 손실되지 않음을 의미합니다.
데이터베이스가 내구성을 보장하는 방법
PostgreSQL과 같은 최신 데이터베이스는 Write‑Ahead Logging (WAL) 라는 메커니즘을 사용합니다. 실제 데이터에 변경을 적용하기 전에 데이터베이스는 이를 로그 파일에 기록합니다. 충돌이 발생할 경우 시스템은 이 로그를 재생하여 최신 커밋된 상태를 복원합니다. 이를 통해 커밋된 트랜잭션이 예상치 못한 실패에서도 살아남게 됩니다.
송금에서 멱등성 처리
실제 결제 시스템에서는 네트워크 재시도, 타임아웃, 클라이언트 측 오류 등으로 인해 하나의 거래 요청이 여러 번 전송될 수 있습니다. 이를 적절히 처리하지 않으면 중복 송금이 발생하여 잔액이 잘못되고 재무 일관성이 깨집니다.
중복 거래 시뮬레이션
Alice가 Bob에게 ₹200을 송금하는 상황이 여러 번 실행된다고 가정해 보세요:
- 첫 번째 실행: Alice → 800, Bob → 700
- 두 번째 실행 (중복): Alice → 600, Bob → 900
같은 작업이 반복 적용되어 원치 않는 차감 및 적립이 발생합니다.
문제 관찰
데이터베이스는 각 요청을 독립적으로 처리합니다. 추가적인 보호 장치가 없으면 거래가 이미 실행되었는지 인식하지 못합니다. 그 결과 중복 요청이 반복 업데이트를 일으킵니다.
왜 위험한가
- 사용자가 여러 번 청구될 수 있다.
- 계좌 잔액이 부정확해진다.
- 시스템에 대한 신뢰가 감소한다.
실제 시스템이 이를 방지하는 방법
- 고유 거래 ID – 각 거래에 고유 식별자를 부여한다. 처리 전에 시스템이 해당 ID가 이미 존재하는지 확인하고, 존재하면 요청을 무시한다.
- 멱등성 키 – 클라이언트가 각 요청에 고유 키를 보낸다. 서버는 이 키를 저장하고 동일한 키를 가진 반복 요청이 재처리 없이 동일한 결과를 반환하도록 보장한다.
- 데이터베이스 제약조건 – 거래 식별자에 고유 제약조건이나 인덱스를 적용하여 데이터베이스 수준에서 중복 입력을 방지할 수 있다.
Transaction Logs
거래 기록을 유지하면 요청이 이미 완료되었는지 확인하는 데 도움이 됩니다.