주뇽's 저장소

트랜잭션과 비관적 락킹 활용하기 💡 본문

웹개발

트랜잭션과 비관적 락킹 활용하기 💡

뎁쭌 2024. 11. 15. 21:06
728x90
반응형

포인트 지급의 동시성 제어 - 트랜잭션과 비관적 락킹 활용하기 💡

포인트를 지급하는 과정에서 동일 계정에 대한 동시 요청으로 포인트가 중복 지급되는 문제가 발생했다. 이러한 동시성 문제를 해결하기 위한 다양한 방법과 최적의 해결책을 알아보자.

1. 문제 상황 - 경쟁 상태로 인한 포인트 중복 지급 🚨

현재 코드의 문제점

  • 포인트 지급 로직이 트랜잭션으로 묶여있지 않음
  • 포인트 지급 여부 확인과 실제 지급 사이의 시간 간격 존재
  • 동일 계정에서 동시에 여러 요청이 들어올 경우 모든 요청이 성공하여 포인트 중복 지급

경쟁 상태 발생 시나리오

  1. 요청 A: 포인트 지급 여부 확인 (미지급 확인)
  2. 요청 B: 포인트 지급 여부 확인 (미지급 확인)
  3. 요청 A: 포인트 지급 실행
  4. 요청 B: 포인트 지급 실행 (중복 지급)

2. 동시성 제어를 위한 다양한 해결방안 🔍

A. 트랜잭션 처리 방식

1. 낙관적 락킹 (Optimistic Locking)

  • 버전 정보를 통한 충돌 감지
  • 충돌 시 재시도 로직 필요
  • 장점: 락 대기 시간 없음
  • 단점: 충돌 시 재시도로 인한 오버헤드

2. 비관적 락킹 (Pessimistic Locking)

  • SELECT FOR UPDATE를 통한 행 레벨 락 획득
  • 동시 접근 원천 차단
  • 장점: 확실한 동시성 제어
  • 단점: 락 대기 시간 발생 가능

B. 애플리케이션 레벨 해결방안

  1. 분산 락 메커니즘
    • Redis 기반 락
    • ZooKeeper 락
    • etcd 락
  2. 프로세스/스레드 락
    • 세마포어
    • 뮤텍스
    • 스핀락

3. 최적의 해결방안: 트랜잭션 + 비관적 락킹 🎯

선정 이유

  1. 신뢰성
    • 포인트 지급은 금전적 가치와 직결되는 중요 작업
    • 실패보다는 대기가 더 나은 선택
    • 확실한 동시성 제어 필요
  2. 단순성
    • 복잡한 재시도 로직 불필요
    • 명확한 트랜잭션 범위 설정 가능
    • 디버깅이 용이
  3. 성능
    • 짧은 트랜잭션 시간
    • 최소한의 락킹 범위
    • 일반적으로 동시 요청이 많지 않은 상황

구현 전략

  1. 트랜잭션 시작
  2. SELECT FOR UPDATE로 마케팅 동의 정보 조회 및 락 획득
  3. 포인트 지급 여부 확인
  4. 포인트 지급 및 상태 업데이트
  5. 트랜잭션 종료

비교 요약표 📝

해결방안 동시성 제어 방식 장점 단점
낙관적 락킹 버전 정보로 충돌 감지 락 대기 없음 충돌 시 재시도 필요
비관적 락킹 SELECT FOR UPDATE 확실한 동시성 제어 락 대기 시간 발생 가능
SERIALIZABLE 완전한 직렬화 완벽한 동시성 제어 심각한 성능 저하

결론: 상황에 맞는 동시성 제어 전략 선택하기 🚀

포인트 지급과 같이 데이터 정합성이 중요한 경우, 트랜잭션과 비관적 락킹의 조합이 가장 적합하다. 이는 구현이 단순하면서도 확실한 동시성 제어가 가능하기 때문이다. 다만, 시스템의 특성과 요구사항에 따라 다른 전략을 선택할 수도 있으므로, 각 방식의 장단점을 잘 이해하고 적절한 전략을 선택하는 것이 중요하다.