READ UNCOMMITTED말 그대로 UNCOMMITTED 데이터를 읽는다는 뜻
dirty read 문제 발생
READ COMMITTEDUNCOMMITTED 데이터는 무시함
해당 레코드의 트랜잭션 아이디가 활성 트랜잭션 목록에 있으면(트랜잭션이 안끝났으면) 무시함
하지만 트랜잭션 중간에 다른 트랜잭션이 커밋하면 데이터가 바뀜
non-repetable read 문제 발생
REPETABLE READ트랜잭션 중간에 다른 트랜잭션이 커밋해도 해당 데이터 무시함
내 트랜잭션 시작시 진행중인 트랜잭션 + 내 트랜잭션 이후에 시작한 트랜잭션(내 트랜잭션 id보다 큰 트랜잭션)
만약 레코드의 트랜잭션 아이디가 위에 포함되면 무시함
phantom read 문제 발생할 수 있음
gap lock 이란?
SELECT * FROM users WHERE age BETWEEN 20 AND 30 FOR UPDATE쿼리처럼 특정 범위 사이에 있는 레코드를 전부 락걸때
지금 있는 레코드만 락걸면 나중에INSERT INTO users (id, age, name) VALUES (999, 25, 'phantom')처럼 사이에 insert 하는건 막을 수 없음
그래서 현재 있는 레코드 락 거는것 뿐만아니라 범위 전체를 락 거는걸gap lock이란걸 사용해서 해결함
InnoDB는 REPETABLE READ에 gap lock을 사용해서 phantom read 방지
select for update쿼리는 mvcc 사용 안해서 gap lock 사용 안하면 insert시 phantom read 가능
https://parkmuhyeun.github.io/woowacourse/2023-11-28-Repeatable-Read/
gap lock 주의점
gap lock을 걸 때
supremum pseudo-record이 걸려서 해당 레코드보다 큰 값 insert가 안될 수 있음
https://velog.io/@haron/MySQL-%EC%9D%B8%EB%8D%B1%EC%8A%A4%EA%B0%80-%EC%9E%88%EB%8A%94%EB%8D%B0-%EC%99%9C-INSERT%EA%B0%80-%EB%8C%80%EA%B8%B0%ED%95%98%EC%A7%80
SERIALIZABLE모든 쿼리문에 락을 걸어준다.