지급 로직 고려 사항

박태현·2025년 6월 22일
0

예약 프로젝트

목록 보기
5/8

따닥 이슈


동일 API 호출이 중복으로 일어나게 될 때 발생하는 현상
비즈니스 로직에서 예외 처리를 해주어도, 여러 요청이 동시에 로직을 타게 되어 예외가 발생하지 않고 통과

예매 로직에서 is_reserved = false 조건에 의해 두 요청이 모두 통과가 되게 됨
⇒ 같은 좌석이 두 명에게 예매됨

왜 이런 현상이 ?
단일 트랜잭션 안에서는 해당 좌석이 아직 예매되지 않은 것처럼 보이기 때문
트랜잭션은 커밋되기 전까지는 DB에 반영되지 않기 때문에 두 트랜잭션이 동시에 seat.is_reserved == false에 의해 각각 통과해버림

⇒ 이는 락을 통해 해결 가능

DB 트랜잭션 이슈


하나의 트랜잭션에 내부 비즈니스 로직과 외부 클라이언트 호출 로직을 함께 사용하면 내부 비즈니스 로직을 아무리 빨리 처리한다고 해도 외부 클라이언트 호출 로직이 느리게 처리되면 API 응답 시간이 길어지게 됨

이를 해결하기 위해 내부 로직이 외부 로직에 영향을 받지 않도록 트랜잭션을 분리

내부 비즈니스 로직은 트랜잭션을 사용하고, 외부 클라이언트 호출 로직은 트랜잭션을 사용하지 않도록 하여
내부 비즈니스 로직은 DB에 저장되어 있는 데이터를 사용하지만, 외부의 추천 로직에 이슈가 있는 경우 빈 리스트를 응답하고 DB에 있는 별도의 데이터를 응답하도록 처리

이처럼 트랜잭션을 분리하여 외부 시스템에 에러가 발생한 경우 예외를 던지지 않고 내부 시스템 데이터를 활용하는 별도 로직으로 처리할 수 있으며, 외부 시스템에 재처리 요청을 하거나 서버 밖으로 예외를 던질 수도 있음

멱등성


같은 연산을 여러 번 수행해도 결과가 처음 한 번 수행했을 때와 동일하게 유지되는 성질을 의미

즉, 어떤 리소스에 대해 A라는 요청을 보냈을 때 B라는 응답을 받았다면, 그 리소스의 상태가 바뀌지 않는 한 A 요청은 반복적으로 보내더라도 항상 동일한 응답 B를 반환해야 함

ex ) 1을 무한히 곱하는 것, 절대값 함수

같은 연산은 항상 같은 결과를 내는 의미가 아님 !!

PUT /user/1 { "name": "Kim" } → 요청을 한 번 보내든 여러 번 보내든 결과적으로 사용자 1의 이름은 kim으로 항상 유지됨 → 멱등성 o

POST /order → 요청을 2번 보내면 주문이 2번 생성됨 → 시스템 상태가 달라짐 → 멱등성 x

만약 멱등성이 지켜지지 않는다면 동일한 작업이 여러 번 처리되어 리소스 낭비가 발생하고, 데이터 불일치 문제가 발생할 수 있으며 동일한 요청에 대해 다른 결과가 반환되어 시스템의 신뢰성이 떨어질 수 있음

케이스 1

중복 요청은 가장 처음 시도만 성공, 이후부터는 예외 던짐 ( 멱등성 x )
1차 요청: 지급 성공 → 성공 응답
2차 요청: 내부 API에서 중복 예외 → 실패 예외 던짐

=> 같은 요청인데 결과가 다름 → 멱등성 위반

케이스 2

먼저 지급 이력을 확인
지급 이력이 있을 때, 중복 요청이 들어오면, 이력을 조회해서 같은 응답을 반환
지급 이력이 없을 때는 지급을 위해 외부 클라이언트를 호출하여 성공 시 지급 후 성공 이력 저장, 실패 시 실패 이력 저장하고 예외

외부 API 호출이 성공할 요청을 여러 번 보내는 경우, 최초 요청에서는 지급 이력이 없기 때문에 외부 API를 호출하여 성공 응답을 반환하고 이력을 저장하고 이후 동일한 요청이 들어오면 저장된 이력을 바탕으로 항상 동일한 성공 응답을 반환하므로 멱등성이 보장됩니다.

반대로 외부 API 호출이 실패할 요청을 여러 번 보내는 경우, 최초 요청에서는 외부 API 호출 실패 후 실패 이력을 저장하고 예외를 반환하고, 이후 동일한 요청이 반복되더라도 저장된 실패 이력을 바탕으로 동일한 예외 응답을 반환하므로 이 경우에도 멱등성이 보장됩니다.

즉, 외부 API가 성공하든 실패하든, 한 번 처리된 요청에 대해서는 항상 동일한 응답(성공 또는 실패)을 반환하므로 전체 로직은 멱등성을 만족

profile
꾸준하게

0개의 댓글