멱등성과 동시성을 보장한다는 것

stanley.·2025년 4월 15일
0

[내가 헷갈려서 정리하는 내용]

결제 시스템을 구축하다 보면, 멱등성과 동시성을 모두 보장해줘야 한다.

위 두가지 개념을 시스템 내에서 왜 보장해야 하는지 그리고 어떻게 보장할 수 있는지 정리해보자.

😎 멱등성 보장 vs 동시성 보장

항목멱등성 보장동시성 보장
초점같은 요청이 여러 번 들어오는 것에 대한 처리서로 다른 요청이 동시에 들어오는 것에 대한 처리
문제 상황네트워크 재전송, 중복 요청여러 사용자/스레드가 같은 자원을 동시에 수정
목적중복 요청으로 인한 부작용 방지데이터 무결성과 일관성 유지
예시같은 결제 요청을 여러 번 보내도 1번만 결제됨여러 사용자가 동시에 재고 1개 구매 시 1명만 성공해야 함

😎 멱등성과 동시성을 동시에 보장하는 방법은 ?

1. db 선점 방식

  1. DB에서 선점(INSERT) 시도 → 실패하면 이미 누군가 처리 중
    방법 A: DB의 PK 제약조건 활용 (가장 단순하고 강력한 방법)
try {
    idempotencyService.reserveKey(idempotencyKey); // INSERT only
} catch (DuplicateKeyException e) {
    // 이미 누가 처리 중이거나 완료된 키
    return idempotencyService.getResponse(idempotencyKey)
           .map(res -> ResponseEntity.ok(res))
           .orElse(ResponseEntity.status(409).body("이미 처리 중입니다."));
}

reserveKey 메서드 예시

public void reserveKey(String key) {
    IdempotencyEntity entity = new IdempotencyEntity(key, null); // 아직 응답 없음
    idempotencyRepository.save(entity); // 중복이면 DuplicateKeyException 발생
}

2. 분산 락 (예: Redis RedLock) – 요청 간 락을 걸어 하나만 처리되게

  1. 요청 전에 Redis에 SET key value NX PX 30000으로 락 시도
  2. 락 성공 → 처리 시작
  3. 락 실패 → 대기 또는 기존 결과 반환
  4. 처리 완료 후 response 저장 + 락 해제
  • 이 방식은 멀티 인스턴스 환경에서도 안정적으로 동작한다.

😎 무결성 제약조건도 충분히 강력한데 레디스를 사용하는 이유?

레디스 사용 이유설명
성능Redis는 인메모리 기반 → DB보다 훨씬 빠름 (μs 단위 응답)
부하 분산DB에 모든 요청이 몰리면 병목 발생 → Redis로 트래픽 분산
TTL 관리가 쉬움Redis 키는 만료시간 설정이 쉬워서 자동 정리 가능
분산 락 기능RedLock 등으로 멀티 인스턴스 환경에서 락 동기화 가능
비즈니스 응답 저장보다 "락만" 필요할 때 유용응답을 DB에 저장하고, 락만 Redis로 처리하는 패턴도 많음
유연성다양한 자료구조, Expire 설정, 간단한 pub/sub 기능 등으로 상황별 대응 가능

😎 DATABASE 선점 방식 vs Redis Lock

항목DB 제약조건 (PK 방식)Redis (락 방식)
속도상대적으로 느림 (디스크 기반)매우 빠름 (메모리 기반)
복잡도낮음 (INSERT로 충분)락 획득/해제 로직 필요
멀티 인스턴스 대응별도 고려 필요 (DB로는 락 제어 어려움)RedLock 등으로 쉽게 분산 락
TTL 관리직접 구현해야 함기본 기능으로 지원
응답 저장 여부대부분 저장함보통은 락만 Redis, 응답은 DB
profile
🖥 Junior Developer.

0개의 댓글