CS공부를 하면 트랜잭션 격리수준을 만나게 된다. 데이터베이스에서 어려운 난이도에 속하는 친구라 생각한다. 해당 내용을 이해하기 위해선 다음과 같은 내용을 이해하는 것이 필수적이다
트랜잭션이란 무엇인가? 데이터베이스에 접근하는 하나의 작업을 수행하는 단위이다.
트랜잭션은 하나의 쿼리로 이루어 질 수 도 있고, 여러개의 쿼리로 이루어 질 수도 있다.
그리고, 트랜잭션은 여러개가 동시에 실행될 수 있다. 그리고 이 때 동시성 제어를 하지 못한다면, 다양한 문제가 발생할 수 있다. 이것을 해결하기 위해 DBMS는 4가지의 격리수준을 제공한다.
가장 높은 격리수준이다. 트랜잭션을 순차적으로 수행하며, 어떠한 트랜잭션도 동일한 레코드에 접근할 수 없다.
문제가 발생하는 상황을 모두 없애버렸으니, 동시성 제어에 문제가 발생하지 않는다. 다만 그만큼 성능이 매우 떨어지기 때문에, 사용을 지양한다.
반복 읽기라는 뜻으로, 하나의 트랜잭션 내에서 반복된 읽기 작업을 수행할 때 동일한 결과를 보장한다는 뜻이다.
RDBMS는 MVCC를 위해 변경 전의 데이터를 언두 공간에 백업해둔다. 그리고 해당 데이터는 커밋이 되기 전까지 유지되며, 읽기 일관성 및 롤백에 사용된다.
롤백은 트랜잭션이 롤백될 때 원래 데이터로 돌리는 데 사용하는 것이겠거니, 읽기 일관성(Read Consistency)는 뭘까? 이것이 바로 REPEATABLE READ이다.

위 그림과 같은 상황에서, A의 트랜잭션이 종료되지 않은 상황(1번)과 A의 트랜잭션이 종료된 상황(2번)에서의 결과는 어떻게 될까?
REPEATABLE READ에서는 하나의 트랜잭션 내에서는 동일한 결과를 보장해야한다. 따라서 1번 상황이든 2번 상황이든 B의 트랜잭션이 끝나지 않았기 때문에 MangKyu를 반환할 것이다.
다만 REPEATABLE READ는 새로운 레코드를 추가하는 경우엔 부정합이 생길 수 있다.
이 때 SELECT로 조회하였을 때 다른 트랜잭션에 의해 추가된 레코드가 발견되는 것을 Phantom Read라고 한다.
MySQL에선 대부분의 경우에서 Phantom Read가 발생하지 않는다고 생각해도 좋다.
MVCC를 사용하기 때문에, 일반적인 경우엔 본인의 트랜잭션ID보다 큰 레코드를 무시하면 되므로 Phantom Read가 발생하지 않는다.
대신 MySQL에서SELECT후SELECT FOR UPDATE를 사용하는 특수한 상황에서 발생할 수 있다.SELECT FOR UPDATE는 언두로그가 아닌 테이블에서 데이터를 조회하기 때문이다.
READ COMMITTED란, 커밋된 데이터만 읽을 수 있다 라는 뜻이다.
앞선 격리수준에서 발생했던 Phantom Read에 더하여 Non-Repeatable Read문제도 발생한다.

REPEATABLE READ수준에선 한 트랜잭션 내에서 읽기에는 동일한 결과를 보장했다. 그러나 READ COMMITTED에서는 커밋이 된 데이터라면 전부 읽을 수 있다.
따라서 위의 그림에서, 1번 경우에는 'MinKyu'를 반환하였지만 2번 경우에는 'MangKyu'를 반환한다는 뜻이다.
이것처럼 동일한 트랜잭션 내에서 반복 읽기를 수행하였을 때 결과가 달라지는 것을 Non-Repeatable Read이라고 한다.
READ UNCOMMITTED는 말 그대로 커밋되지 않아도 읽을 수 있다 라는 뜻이다.

위와 같은 상황에서, 동일한 트랜잭션 내의 결과가 동일하지 않을 뿐더러 조회했던 데이터가 갑자기 사라지는 현상이 발생한다. 이것이 Dirty Read 문제이다.
따라서 절대 사용하면 안되는 격리수준이다.

참고 블로그 : https://mangkyu.tistory.com/299
자료 출처 : https://mangkyu.tistory.com/299