- 작성자 : 김다희
- 참여자 : 김다희, 이상민
- 날짜 : 21.11.03.수 /
좌석 선점 동시성 문제를 어떻게 해결할 수 있을까?
- 현 상태
- 예매 페이지 들어갈 때 대기큐는 없는 상황
- 고려해야할 사항
- 동시 접속 규모를 어느정도로 생각하고 갈지
- 해결 가능 방식
- 어플리케이션단 해결 방식
- 낙관적 락
- 인메모리 캐쉬
- 데이터베이스 해결 방식
- 비관적 락
동시성 - 비관적 락
- 티켓 생성 api 트랜잭션으로 관리할것
- 회차 좌석 상태 조회
- 티켓 레코드 생성
- 회차 좌석 상태 변경
- 회차 잔여 좌석 -1
- 동시성 생각해야할 부분
- 위 트랜잭션이 커밋시 다른 동일한 회차 좌석에 대한 트랜잭션이 실패해야함
- 잔여 좌석 -1을 동시성 안전하게
- 1, 2가 한 트랜잭션 안에 있으면 한번만 해결하면 될듯
- 동시성 전략
- 어플리케이션으로 하려면 - 메시징 큐 등
- 회차 좌석 상태 조회시 SELECT FOR UPDATE으로 락을 건다
- 아니면 티켓의 (회차, 좌석)에 유니크 키...? - 데이터베이스에 의존적
- SERIALIZABLE로 격리 수준 상향(동시성 없애기) - 느림
// 동시성 문제 발생 가능한 상황 begin 회차 좌석 상태 조회 begin 티켓 생성 회차 좌석 상태 조회 회차 좌석 상태 변경 티켓 생성 회차 잔여 좌석 - 1 회차 좌석 상태 변경 commit 회차 잔여 좌석 - 1 commit // for update 락 적용시 begin 회차 좌석 상태 조회(락) begin 티켓 생성 회차 좌석 상태 조회 (대기) 회차 좌석 상태 변경 회차 잔여 좌석 - 1 commit 좌석이 이미 차지돼서 실패 commit
- JPA lock
- @Lock(LockModeType.PESSIMISTIC_WRITE) (for update)
- LockModeType.PESSIMISTIC_WRITE 일반적인 옵션. 데이터베이스에 쓰기 락 다른 트랜잭션에서 읽기도 쓰기도 못함. (배타적 잠금)
- LockModeType.PESSIMISTIC_READ 반복 읽기만하고 수정하지 않는 용도로 락을 걸 때 사용 다른 트랜잭션에서 읽기는 가능함. (공유 잠금)
- LockModeType.PESSINISTIC_FORCE_INCREMENT Version 정보를 사용하는 비관적 락
- JPA ISOLATION LEVEL