Skip to content
난이도 면접 빈출문제은행 7

트랜잭션 격리수준 ​

격리 수준(isolation level)은 동시에 실행되는 트랜잭션(transaction)이 서로의 변경을 어디까지 볼 수 있는가를 정하는 규칙이다. 격리를 강하게 할수록 이상 현상(anomaly)은 줄고 동시성은 떨어진다.

왜 필요한가 ​

트랜잭션을 완전히 한 줄로 세워 하나씩 실행하면 안전하지만 느리다. 반대로 아무 제약 없이 섞어 돌리면 변경을 확정하는 커밋(commit)을 아직 하지 않은 값을 읽거나, 같은 행을 두 번 읽었는데 값이 달라지는 일이 생긴다. 격리 수준은 이 둘 사이에서 어떤 이상 현상까지 허용할지를 고르는 다이얼이다. SQL 표준(SQL-92)이 4단계를 정의하고, 엔진마다 실제 동작은 조금씩 다르다.

4단계와 이상 현상 ​

표준이 구분하는 이상 현상은 더티 리드(dirty read), 반복 불가능한 읽기(non-repeatable read), 팬텀 리드(phantom read) 세 가지다. 각각의 뜻은 표 아래에서 설명한다. 표의 "발생"은 그 격리 수준에서 해당 현상이 생길 수 있다는 뜻이다.

격리 수준더티 리드반복 불가능한 읽기팬텀 리드
READ UNCOMMITTED발생발생발생
READ COMMITTED방지발생발생
REPEATABLE READ (InnoDB 기본)방지방지표준은 허용, InnoDB는 대부분 방지*
SERIALIZABLE방지방지방지

* InnoDB의 일반 SELECT는 트랜잭션 내내 같은 읽기 뷰(read view)를 유지하므로 팬텀이 보이지 않는다. 잠금 읽기(locking read)와 UPDATE·DELETE는 넥스트키 락(next-key lock)으로 스캔한 범위에 새 행이 삽입되는 것을 막는다. 다만 잠금 없이 스냅샷(snapshot)을 읽는 일관된 읽기(consistent read)와 잠금 읽기를 한 트랜잭션에서 섞으면 서로 다른 시점의 행이 보일 수 있다. 그래서 "무조건 없다"고 단정하면 안 된다.

세 이상 현상은 이렇게 구분한다.

  • 더티 리드: 다른 트랜잭션이 아직 커밋하지 않은 값을 읽는다. 그 트랜잭션이 롤백(rollback)하면, 읽은 값은 한 번도 확정된 적 없는 값이 된다.
  • 반복 불가능한 읽기: 같은 행을 두 번 읽었는데 사이에 다른 트랜잭션이 그 행을 고치고 커밋해 값이 달라진다.
  • 팬텀 리드: 같은 조건으로 두 번 조회했는데 사이에 다른 트랜잭션이 행을 삽입하거나 삭제해 조건에 맞는 행 집합이 달라진다. 개수가 같더라도 구성원이 바뀌면 팬텀이다.

Non-Repeatable Read 한 장면 ​

다이어그램 로딩…

REPEATABLE READ였다면 T1은 첫 SELECT 시점의 스냅샷을 계속 보므로 두 번째도 100이 나온다.

기억법

격리 수준 4개는 "이상 현상 3개를 위에서부터 하나씩 끈다"로 외운다. READ COMMITTED가 더티 리드를, REPEATABLE READ가 반복 불가능한 읽기를, SERIALIZABLE이 팬텀 리드를 끈다.

면접 포인트 ​

  • "격리 수준 4단계와 막는 이상 현상은?" → READ UNCOMMITTED(다 허용) → READ COMMITTED(더티 리드 방지) → REPEATABLE READ(반복 불가능한 읽기까지 방지) → SERIALIZABLE(팬텀 리드까지 방지).
  • "팬텀 리드와 반복 불가능한 읽기의 차이는?" → 같은 행의 값이 바뀌느냐, 조건에 맞는 행 집합이 바뀌느냐.
  • InnoDB의 REPEATABLE READ는 표준과 달리 팬텀을 대부분 막지만 "무조건 없다"는 아니다.

이어지는 내용은 트랜잭션 격리수준 2에서 다룬다. InnoDB가 스냅샷과 잠금으로 각 수준을 어떻게 구현하는지, 다른 엔진과 무엇이 다른지, 실무에서 무엇을 조심하는지를 본다.

바로 확인 ​

바로 확인 · 3문항
Q1난이도

MySQL InnoDB의 기본 트랜잭션 격리 수준은?

Q2난이도

InnoDB REPEATABLE READ에서 팬텀 리드를 막는 데 쓰이는 잠금은?

Q3난이도 { } 괄호 채우기

현재 세션의 격리 수준을 조회하는 MySQL 8 구문

SELECT @@.transaction_isolation;
빈칸 1 채우기

관련 문서