프로젝트

매장 예약 서비스 - 동시성 문제

Lv.1 ysg 2024. 2. 19. 21:40

매장 예약 서비스를 개발하면서 중요하다고 생각한 제약사항 중 하나는 예약 가능 여부가 중요하다고 생각했었다 그래서 해당 매장에서 예약 하려는 시간대의 남아있는 테이블 수를 계산해 예약 가능 여부를 체크했었다 하지만 문제는 동시에 예약 요청이 들어오는 경우는 전혀 생각하지 않았었다..

 

동시성 문제

두개의 요청 중 하나의 요청만 예약 가능하다고 할때 매장에다 동시에 예약 요청을 보내게 되면 둘다 예약에 성공한다

예시로 총 테이블 6개를 보유한 매장이 있다 예약 하려는 시간대에 이미 5개의 테이블이 예약되어 있는 상황 즉 테이블 1개만 예약 가능한 상황이다 1개의 테이블 예약 요청을 동시에(같은 시간대에) 보내게 되면 첫번째 요청은 성공해야하고 두번째 요청을 실패해야 하지만 둘다 예약에 성공한다

이런일은 발생하면 안된다고 생각했다..

 

총 테이블수는 6개지만 동시 예약 성공..

 

S_IDX : 매장 고유번호

START_TIME : 예약 요청 시간

RESER_TIME : 예약한 시간

TABLE_CNT : 예약 한 테이블 수

RESER_STAT : 예약 상태

 

 

해결 방법 - 비관적 락 ( 배타 락 )

공유 락 설정

처음에는 비관적 락인 공유 락을 설정 했었다 그랬더니 공유 락은 다른 트랜잭션에서 쓰기는 불가능하지만 읽기는 가능하므로 동시에 조회하게 되어 예약 가능한 테이블의 수가 같게 나와버린다 이렇게 되버리면 예약 가능 여부 체크가 정상적으로 동작하지 못하게 된다

그리고 서로 공유 락을 획득한 상황에서 저장을 위해 배타 락을 획득하려고 하지만 공유 락이 걸려 있어 서로 락이 해제 될때까지 무한정 대기하는 데드락 현상이 발생했었다

 

공유 락 설정 후 에러

 

successReserTableCnt : 예약상태가 성공처리된 테이블 수 (해당 시간대에 이미 예약이 되어있는 테이블 수)

reservationTableCnt : 예약 요청한 테이블 수

storeTableCnt : 매장이 보유한 테이블 수

 

 

배타 락 설정

그래서 배타 락으로 설정하게 되었다 배타 락은 다른 트랜잭션에서 읽기도 불가능 하기 때문에 예약 가능한 테이블의 수가 다르게 나온다 따라서 예약 가능 체크가 정상적으로 동작할 수 있었다

배타 락 설정

 

배타 락 설정 후 정상동작

 

 

이렇게 해서 예약 시스템의 동시성 이슈도 해결 하였다

 

 

참고링크

https://ttlblog.tistory.com/1568#%F0%9F%90%B3%20%EB%82%99%EA%B4%80%EC%A0%81%20%EB%9D%BD(Optimistic%20Lock)-1

 

[Spring] 동시성 문제 해결방법 (2) - 낙관적 락(Optimistic Lock), 비관적 락(Pessimistic Lock)

🤔 서론 이전 글에서 알아본 synchronized는 단일 서버 환경에서만 동시성 문제를 해결할 수 있었습니다. 이번 글에서는 다중 서버 환경에서 동시성 문제를 해결할 수 있는 방법에 대해 알아보도록

ttl-blog.tistory.com

https://isntyet.github.io/jpa/JPA-%EB%B9%84%EA%B4%80%EC%A0%81-%EC%9E%A0%EA%B8%88(Pessimistic-Lock)/

 

JPA 비관적 잠금(Pessimistic Lock)

비관적 잠금(Pessimistic Lock) 이란? 선점 잠금이라고 불리기도 함 트랜잭션끼리의 충돌이 발생한다고 가정하고 우선 락을 거는 방법 DB에서 제공하는 락기능을 사용

isntyet.github.io

https://unluckyjung.github.io/db/2022/03/07/Optimistic-vs-Pessimistic-Lock/

 

낙관적(Optimistic) 락과 비관적(Pessimisitc)락

낙관적(Optimistic) 락과 비관적(Pessimisitc)락 두 락의 차이를 알아봅니다.

unluckyjung.github.io

 

 

https://ksh-coding.tistory.com/121

 

[DB] DB Lock이란? (feat. Lock 종류, 블로킹, 데드락)

0. 락(Lock)이란? 여러 커넥션에서 동시에 동일한 자원을 요청할 경우 순서대로 하나의 커넥션만 변경할 수 있게 해주는 기능 동시성을 제어하기 위한 기능 저는 처음에 DB 락을 접했을 때, 락을 이

ksh-coding.tistory.com

https://studyhardd.tistory.com/86

 

[재고시스템으로 알아보는 동시성이슈 해결방법] 3. Database Lock

동시성 이슈 해결방법 이번 시간에는 Database Lock을 활용한 해결방법을 알아보자. 해결법2. Database ( MySQL ) 데이터베이스의 락을 이용해 동시성 문제를 해결해보자 1. Pessimistic Lock (비관적 락) 자원

studyhardd.tistory.com

https://hudi.blog/mysql-8.0-shared-lock-and-exclusive-lock/

 

MySQL 8.0의 공유 락(Shared Lock)과 배타 락(Exclusive Lock)

락의 종류와 전략은 DBMS 벤더사마다 조금씩 다르다. 본 포스팅은 MySQL 8.0 InnoDB 기준으로 설명한다. DBMS에서 특정 데이터에 대한 동시 접근이 발생한 경우 일관성과 무결성 지키기 위해 해당 데이

hudi.blog

https://parkjeongwoong.github.io/articles/Failure/5

 

Java (Spring Boot) 동시성 테스트

# Java (Spring Boot) 동시성 테스트 ``` 이 글은 한옥 스테이의 예약 시스템을 만들며 마주한 동시성 문제를 해결한 과정을 다룹니다. ``` ## 서론 최근 한옥 스테이에 사용할 예약 시스템을 만들고 있

parkjeongwoong.github.io