인프런 커뮤니티 질문&답변

김현석님의 프로필 이미지
김현석

작성한 질문수

재고시스템으로 알아보는 동시성이슈 해결방법

동시 저장 문제

해결된 질문

작성

·

194

1

안녕하세요 동시 저장 관련하여 질문드립니다.

예약 관련하여 프로젝트를 진행하고 있는데 db에 없는 데이터를 삽입을 해야하는데

동시에 여러 쓰레드가 아래의 servicer계층의 reserve()를 호출하여 예약을 시도할 때 이 메서드의 호출을 하나씩만 처리하기 위해서

@Transactional
public void reserve(ReserveRequest reserveRequest) {
    boolean isExistsReservation = reservationRepository.existsByStartTimeAndEndTime(~~~);
    
    if(!isExistsReservation) {
        reservationRepository.save(~~~);
    }

}
  1. named lock을 사용하여 key를 월+일(1124)와 같이 만들어서 해당 날짜의 예약에 대해서 하나씩만 처리되도록 하여 중복을 막는 방법도 괜찮을까요?

  2. 1번 방법을 사용하지 않고 다른 방법이 있을까요?

  3. service계층의 reserve메서드의 @Transactional의 격리수준을 조절해서도 해결 가능할까요?

 

답변 1

0

최상용님의 프로필 이미지
최상용
지식공유자

김현석님 안녕하세요.

구현하시고자 하는 기능이 어떤것인지 정확히는 알지못하는 관계로 정확한 답변을 드리기는 힘들것 같습니다.

예약과 관련하여 답변을 드리자면

특정날짜 (예를들어 11월 24일) 를 기준으로 일정인원이상의 예약이 불가능한 상황이 있을 수 있습니다.

이 경우에는 말씀해주신 1번의 방법으로 충분할듯합니다. 다만, 년월일을 사용하는것이 좋아보입니다.

반면에 영화관 좌석과같이 날짜 + 특정좌석에 1명밖에 허용을 안하는 상황이 있습니다.

예를들어 11월 24일 xx 영화의 F열 12번 좌석은 1명밖에 예매를 하지 못할것입니다.

이 경우에는 날짜 + 특정좌석의 번호 (key) 를 같이 잡아 주어야합니다.

마지막으로 Transactional 의 격리수준을 변경하는것은 많은 고려가 필요한작업이며 변경하는것이 일반적인 해결방법은 아닙니다.

구현하시고자 하는 기능이 어떤것인지 조금 더 상세하게 알려주신다면 조금 더 자세한 답변을 드릴 수 있을듯합니다.

감사합니다.

 

김현석님의 프로필 이미지
김현석
질문자

자세한 답변감사합니다 강사님! 조금 더 자세히 상황을 말씀드리자면

예시로 6개의 좌석이 존재하고 사용자는 이 좌석을 날짜별로 30분 단위로 예약이 가능합니다.

member1이 1번 좌석을 11월 28일 10:30~12:00까지 예약을 시도하고

member2는 1번 좌석을 11월 28일 10:00~13:00까지 예약을 시도하는 상황이라면

중복이 되어 동시에 예약을 시도하지 못하도록 해야 하는 상황입니다.

named lock의 key를 날짜 + 좌석 번호 "11281"과 같이 설정하는식으로 하면 될까요?

그리고 timeout을 다른 질문글에서 2~5초가 일반적이다라는 것을 봤는데 제 프로젝트 규모상 사용자가 적어서 2초이상 걸릴일은 잘 없겠지만 혹시 성능이슈는 트레이드오프 관계라서 어쩔 수 없는 부분일까요?

최상용님의 프로필 이미지
최상용
지식공유자

김현석님 안녕하세요.

넵 말씀하신대로 날짜 + 좌석번호로 잡아도 될듯합니다.

타임아웃은 서비스마다 상이하기때문에 어느정도가 좋다! 라고 말씀드리기는 좀 힘들것 같습니다.

 

김현석님의 프로필 이미지
김현석
질문자

감사합니다 많은 도움이 되었습니다!

김현석님의 프로필 이미지
김현석

작성한 질문수

질문하기