출처 : https://dololak.tistory.com/446
위에 예시처럼 데이터베이스에서 race condition이 있으면 잔여좌석이 2 줄어들 것이 하나만 줄어드는 문제가 발생할 수 있다
레코드 단위 락을 걸어 이런 문제를 방지할 수 있는데, SELECT FOR UPDATE 또는 LOCK IN SHARE MODE를 사용해볼 수 있다
이 두 구문을 locking read라고 부른다
데이터를 수정하기위해 SELECT하는 중이기 때문에 다른 트랜잭션이 레코드를 SELECT하지 못하게 read, write락을 거는 구문
SELECT 컬럼 FROM 테이블 WHERE 조건 FOR UPDATE;
출처 : https://dololak.tistory.com/446
SELECT의 대상이 되는 레코드들에 read, write 락을 걸어 다른 locking read가 레코드를 조회하거나 레코드를 수정할 수 없게 한다
기본적으로 락을 획득할때까지 무한정 기다린다. FOR UPDATE NOWAIT(= WAIT 0)처럼 옵션을 주어 락을 바로 획득하지 못할 시 예외를 발생하도록 할 수도 있다
FOR UPDATE를 사용한 트랜잭션이 커밋되어야 락이 풀린다
정리 : 선택한 레코드가 트랜잭션의 커밋 전 수정될 수 있으니 다른 트랜잭션이 read lock을 얻거나 수정할 수 없게 한다
선택된 레코드들에 shared 락, write 락을 거는 구문
SELECT의 대상이 되는 레코드들에 write 락을 걸어 다른 트랜잭션이 수정할 수 없게 한다. FOR UPDATE와는 다르게 읽기는 가능하다
FOR UPDATE와 동일하게 락을 획득할때까지 기다린다
LOCK IN SHARE MODE를 사용한 트랜잭션이 커밋되어야 락이 풀린다
SHARED LOCK이 이미 걸려 있어도 다른 트랜잭션이 LOCK IN SHARE MODE를 사용할 수 있다. 이때 두 트랜잭션이 레코드를 수정하려고 하면, 서로의 락에 의해 데드락이 발생한다. 먼저 UPDATE를 시도한 트랜잭션이 타임아웃되어서 실패하고, 다른 트랜잭션이 성공한다. 결과적으로 하나의 수정만 성공한다
정리 : 선택한 레코드를 읽기만하고 수정하지 않는다. 여러 트랜잭션이 read lock을 얻을 수 있다. 해당 레코드를 수정하는 트랜잭션은 락이 풀리기를 기다려야한다
https://dololak.tistory.com/446
https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html