동시성 문제 - comento-backend-camp/ticket-reservation-server-hyejung GitHub Wiki

동시성 문제

실제 서비스 운영에서는 초당 1개의 서버가 받는 요청은 200tps는 기본, 많으면 1000, 10000 까지도 올라갈 수 있음. (tps : 1초당 처리되는 트랜잭션 타임)

ex. 같은 좌석을 동시에 10000명의 사용자가 동시에 예약 시도를 한다면?

동시성 이슈를 처리하지 않을 경우 10000명 모두 예약에 성공하게 됨.

즉, 동시성 문제를 해결할 수 있어야 함

  • RDBMS의 테이블에 동시에 여러 커넥션이 같은 테이블의 row를 수정하면 데이터가 예상과 다르게 변경되는 문제 발생
  • 이를 해결하기 위해 RDBMS에서는 Lock을 통해 동시성을 제어하여 ACID를 보장

해결방법

  1. 분산락을 적용하는 방법
    1. 최고 수준의 격리 수준(MySQL의 경우, SERIALIZABLE)으로 설정
      1. 쿼리별로 lock을 건다.
        • 동시에 실행되는 경우 데드락 상태에 빠질 수 있음
        • ex. T1과 T2가 좌석의 예약현황을 조회할때 S락을 걸어버리고 T1과 T2가 reservation 테이블에 insert시키고 해당 좌석의 예약상태를 완료로 변경할때 X Lock을 걸려고 시도하는데 T1이 S락으로 해당 row을 점유하고 있고 T2또한 S락으로 해당 row를 점유하고 있기때문에 T1,T2는 서로 S락을 소유하고있지만 X락을 획득하려고 하면서 데드락 상태에 빠지고 timeout으로 두개의 트랜잭션은 모두 실패
      2. row별로 lock을 건다
        • SELECT .. FOR UPDATE 문을 이용
        • FOR UPDATE 구문은 Seriazable레벨에 비해서 데드락은 줄일 수 있음.
        • FOR UPDATE문은 타임아웃 구성이 까다롭기 때문에 무한 대기에 빠질수 있음.
  2. Redis를 이용하는 방법
    1. 싱글스레드로 이루어져있으므로 들어온 순서로 처리하기에 동시성 문제가 발생되지 않음.