458. 고립화 수준 (Isolation Level)

⚠️ 이 문서는 "내 트랜잭션을 완벽하게 보호할 것인가(데이터 정합성), 아니면 살짝 위험하더라도 남들이 빨리빨리 일하게 해 줄 것인가(동시성)" 사이의 딜레마를 해결하기 위해, **데이터베이스가 제공하는 4단계의 자물쇠 강도 조절 옵션인 '고립화 수준'**을 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 트랜잭션의 4대 특성(ACID) 중 고립성(Isolation - 443번 문서)을 현실적인 비즈니스 환경에 맞춰 타협하기 위한 4단계 레벨 설정이다.
  2. 트레이드오프: 격리 수준이 낮을수록 동시 처리 속도는 빨라지지만, 오손 읽기(Dirty Read) 같은 이상 현상이 발생한다. 반대로 격리 수준이 높을수록 데이터는 완벽하게 안전해지지만 속도가 끔찍하게 느려진다.
  3. 표준: 대부분의 상용 데이터베이스는 성능과 안전성의 황금 밸런스인 Read Committed(Oracle 기본값)나 Repeatable Read(MySQL 기본값)를 디폴트로 사용한다.

Ⅰ. 개요: 완벽한 방어의 대가 (Context & Necessity)

가장 완벽한 데이터베이스는 한 번에 한 명씩만 줄을 세워서 처리하는 것이다. (100% 직렬화) 하지만 수만 명이 접속하는 쇼핑몰에서 1열 종대로 줄을 세우면, 내 앞사람이 결제를 끝낼 때까지 나는 상품 목록조차 볼 수 없게 된다. 서버는 1초 만에 마비된다.

따라서 아키텍트는 **"살짝 에러가 나도 되니까 여러 명이 한꺼번에 들어와서 쓰게 하자"**라고 타협을 해야 한다. 이 타협의 스위치가 바로 **고립화 수준(Isolation Level)**이다.

📢 섹션 요약 비유: 고립화 수준은 **'코로나 방역 단계'**와 같습니다. 4단계(Serializable)는 모두가 집 밖에 못 나오게 완벽 차단하지만 경제(성능)가 박살 납니다. 1단계(Read Uncommitted)는 아무도 마스크를 안 쓰고 돌아다녀서 경제는 활발하지만 전염병(데이터 꼬임)이 창궐하죠. 그래서 현실에서는 2~3단계로 타협하며 살아갑니다.


Ⅱ. 4단계 격리 수준 완벽 정리 ★

각 레벨에서 어떤 이상 현상(Anomaly)이 발생하고 방어되는지 무조건 외워야 한다.

Level 0: Read Uncommitted (커밋되지 않은 읽기)

  • 특징: 자물쇠(Lock)가 아예 없다. 남이 UPDATE 중이고 아직 COMMIT도 안 한 데이터를 내가 막 읽어간다.
  • 발생 현상: Dirty Read(오손 읽기, 446번 문서) 발생. 남이 롤백해버리면 나는 가짜 데이터를 들고 있게 됨.
  • 실무: 데이터가 꼬여도 상관없는 대충 보는 통계(예: 오늘 접속자 수) 빼고는 절대 안 쓴다.

Level 1: Read Committed (커밋된 읽기)

  • 특징: "남이 COMMIT 도장을 쾅 찍은 데이터만 읽을게!" (가장 많이 쓰는 옵션)
  • 발생 현상: Dirty Read는 방어된다. 하지만 내가 쿼리를 2번 날릴 때, 중간에 남이 데이터를 고쳐버려서 1번째와 2번째 쿼리 결과가 달라지는 **Non-Repeatable Read(반복 불가능 읽기, 447번 문서)**가 발생한다.

Level 2: Repeatable Read (반복 가능한 읽기)

  • 특징: 내가 트랜잭션을 시작하면, 나만의 스냅샷(MVCC)을 찍어놓고 남이 고치든 말든 계속 내 사진만 본다.
  • 발생 현상: Non-Repeatable Read 방어 성공! 하지만 내가 읽는 동안 남이 '새로운 줄'을 INSERT 해버리면, 없던 유령 데이터가 갑자기 뿅 하고 나타나는 **Phantom Read(유령 읽기, 448번 문서)**가 발생한다.

Level 3: Serializable (직렬화 가능)

  • 특징: 완벽한 격리. 내가 SELECT로 읽고 있는 테이블에는 남이 UPDATE도, INSERT도 절대 못 한다.
  • 발생 현상: 모든 이상 현상(Dirty, Non-Repeatable, Phantom) 방어 성공!
  • 실무: 성능이 미친 듯이 떨어지기 때문에 (수만 명이 무한 대기함) 거의 쓰지 않는다.

Ⅲ. 실무 요약 매트릭스

정보처리기사 시험에 표 채우기 문제로 100% 출제된다. O(방어 성공), X(방어 실패, 버그 발생)

격리 수준 (Isolation Level)Dirty Read (오손 읽기)Non-Repeatable ReadPhantom Read (유령 읽기)
Read Uncommitted (Lv.0)❌ 발생함❌ 발생함❌ 발생함
Read Committed (Lv.1)🟢 방어됨❌ 발생함❌ 발생함
Repeatable Read (Lv.2)🟢 방어됨🟢 방어됨❌ 발생함
Serializable (Lv.3)🟢 방어됨🟢 방어됨🟢 방어됨

Ⅳ. 결론

"완벽한 일관성은 비즈니스의 적이다." 개발자들이 처음 데이터베이스를 배우면 "데이터가 꼬이지 않게 무조건 Serializable로 락을 꽉꽉 잠가야지!"라고 생각한다. 하지만 트래픽이 몰리는 실제 서비스에서 그런 세팅은 서버 장애 1순위 원인이 된다. 현업의 시니어 개발자들은 기본적으로 Read CommittedRepeatable Read를 깔아두고, 돈이 오가는 결제 로직이나 재고 차감 같은 아주 치명적이고 짧은 로직에만 FOR UPDATE나 낙관적 락(Optimistic Lock - 445번 문서)을 걸어 핀셋처럼 동시성(Concurrency)을 방어한다. 이것이 트레이드오프(Trade-off)의 미학이다.


📌 관련 개념 맵

  • 관련 특성: 고립성 (Isolation - 443번 문서), 2PL (2단계 잠금 규약 - 450번 문서)
  • 이상 현상 모음: Dirty Read(446번), Non-Repeatable Read(447번), Phantom Read(448번)
  • MySQL 특징: MySQL(InnoDB)은 Repeatable Read 환경에서도 'Gap Lock'이라는 기술로 Phantom Read를 막아준다.

👶 어린이를 위한 3줄 비유 설명

  1. 0단계(Read Uncommitted)는 동생이 일기장에 글을 쓰다 말고 화장실 간 사이에 몰래 훔쳐보는 거예요.
  2. 1단계(Read Committed)는 동생이 일기장을 다 쓰고 서랍에 넣은(Commit) 완벽한 일기장만 보는 거예요.
  3. 3단계(Serializable)는 내가 일기장을 꺼내서 읽고 있으면, 동생이 내 방에 아예 못 들어오게 방문을 잠가버리는(완벽 격리) 거랍니다!