: commit 되지 않은 변화를 읽음

트랜잭션2가 write를 했는데 commit되기 전에 트랜잭션1이 read하면서 나타나는 현상.
뒤에서 트랜잭션2가 rollback을 하게 되니까 최종적으로 x,y 둘 다 유효하지 않은 값을 가지게 되는 것.
: 같은 값을 반복해서 read했는데 각각 다른 값이 나오는 것.
트랜잭션의 isolation 속성(여러 트랜잭션이 동시에 실행돼도 각각의 트랜잭션이 마치 하나로 동작하는 것처럼 실행돼야함) 을 위반하게 됨.

: 없던 데이터가 생기는 것.
이 또한 isolation 속성 위반.

위의 현상들을 모두 발생하지 않게 만들 수 있지만 그러면 제약사항이 많아져서 동시 처리 가능한 트랜잭션의 수가 줄어들어 결국 DB의 전체 처리량(throughput)이 하락하게 된다
-> 일부만 허용하는 level을 만들어 사용자가 필요에 따라 선택할 수 있도록 함.

특히 Serializable은 3개의 현상뿐만 아니라, 아예 이상한 현상이 발생하지 않는 level을 의미한다.
애플리케이션 설계자는 isolation level을 통해 전체 처리량과 데이터 일관성 사이에서 어느 정도 타협할 수 있다.
: 위의 표준에서 정의한 isolation과는 약간 다름.
표준 - 이상한 3가지 현상들이 '정의된 것들 중'에서 얼만큼 허용하는지에 따라 level을 부여
snapshot isolation - concurrency control이 어떻게 동작할지의 '구현'을 바탕으로 정의된 isolation level.

트랜잭션 시작 전에 commit된 데이터만 보이므로 트랜잭션1에서 read(y)를 실행해도 트랜잭션1이 화살표 시점에서 시작됐기 때문에 그 시점을 기준으로 y의 값을 가져옴. 그래서 트랜잭션2에서 commit된 150이 아닌 50을 읽게 됨.
같은 데이터에 대해 같은 write가 발생했을 때는 먼저 커밋한 트랜잭션2가 승리자가 됨.
출처: https://www.youtube.com/watch?v=bLLarZTrebU&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=17