네 가지 격리 수준
커밋되지 않은 읽기부터 직렬화 가능 수준까지, 각 수준에서 허용되는 동작을 알아봅니다.
네 가지 격리 수준은(는) CoddyKit의 무료 Coding Interview Prep 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Coding Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
질문 뒤에 숨은 질문
면접관이 "네 가지 격리 수준을 말해 보세요"라고 질문할 때 실제로 확인하려는 것은 상충 관계를 설명할 수 있는지입니다. 격리성이 강할수록 이상 현상은 줄어들지만 동시성은 낮아집니다.
표준은 네 가지 수준을 가장 약한 것부터 가장 강한 순서로 정의합니다.
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
각 수준은 특정한 읽기 이상 현상들을 허용하거나 금지합니다. 이 수업에서는 수준을 다루고, 다음 수업에서는 이상 현상을 자세히 다룹니다.
격리 수준 설정하기
격리 수준은 트랜잭션별 또는 세션별로 설정합니다. 구문은 엔진마다 거의 동일합니다.
설정하지 않으면 모든 데이터베이스에 기본값이 있습니다. 기본값을 아는 것은 면접에서 자주 나오는 질문이므로 마지막에 다룹니다.
-- Per transaction (standard SQL)
BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- ... statements ...
COMMIT;
-- Per session
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;1단계: READ UNCOMMITTED
READ UNCOMMITTED는 가장 약한 수준입니다. 트랜잭션은 다른 트랜잭션이 변경했지만 아직 커밋하지 않은 행을 읽을 수 있습니다. 이를 더티 리드라고 합니다.
다른 트랜잭션이 롤백하면 실제로 공식적으로 존재한 적이 없는 데이터를 읽은 셈입니다. 정확성이 중요한 작업에서는 위험합니다.
참고: PostgreSQL은 READ UNCOMMITTED를 READ COMMITTED와 동일하게 처리하므로 실제로 더티 리드를 수행하지 않습니다. 에스큐엘 서버와 MySQL은 이 수준을 실제로 적용합니다.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN;
-- may see another transaction's uncommitted (dirty) rows
SELECT balance FROM accounts WHERE id = 1;
COMMIT;2단계: READ COMMITTED
READ COMMITTED는 커밋된 데이터만 읽도록 보장합니다. 더티 리드는 발생하지 않습니다.
하지만 각 문은 가장 최근에 커밋된 스냅샷을 봅니다. 하나의 트랜잭션에서 같은 쿼리를 두 번 실행하면 그 사이에 커밋된 다른 트랜잭션이 결과를 바꿀 수 있습니다. 이 이상 현상을 비반복 읽기라고 합니다.
이 수준은 PostgreSQL, 오라클, 에스큐엘 서버의 기본값이며 대부분의 애플리케이션에 합리적인 균형을 제공합니다.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
SELECT balance FROM accounts WHERE id = 1; -- returns 500
-- another transaction commits an update to id = 1
SELECT balance FROM accounts WHERE id = 1; -- may now return 700
COMMIT;3단계: REPEATABLE READ
REPEATABLE READ는 같은 트랜잭션에서 한 행을 두 번 읽으면 두 번 모두 같은 값을 얻도록 보장합니다. 트랜잭션이 시작될 때 일관된 스냅샷을 생성합니다.
더티 리드와 비반복 읽기를 방지합니다. 하지만 표준에서는 여전히 팬텀 읽기를 허용합니다. 팬텀 읽기란 WHERE 절과 일치하는 새 행이 다시 조회할 때 나타나는 현상입니다.
중요: 이 수준은 MySQL/InnoDB의 기본값이며, InnoDB의 구현은 다음 키 잠금을 사용하여 대부분의 팬텀도 차단합니다.
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
SELECT balance FROM accounts WHERE id = 1; -- 500
-- another transaction commits a change to id = 1
SELECT balance FROM accounts WHERE id = 1; -- still 500 in this txn
COMMIT;4단계: SERIALIZABLE
SERIALIZABLE은 가장 엄격한 수준입니다. 데이터베이스는 트랜잭션을 동시에 실행한 결과가 어떤 직렬 순서로 하나씩 실행한 결과와 동일하도록 보장합니다.
더티 리드, 비반복 읽기, 팬텀 읽기를 모두 방지합니다. 그 대가로 잠금이 더 많이 필요하거나 PostgreSQL에서는 직렬화 실패로 트랜잭션이 중단될 수 있어 재시도해야 합니다.
면접에서의 표현: "SERIALIZABLE은 동시성을 낮추고 재시도가 필요할 수 있다는 대가로 모든 트랜잭션이 혼자 실행된 듯한 효과를 제공합니다."
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT SUM(balance) FROM accounts;
INSERT INTO audit (total) VALUES (...);
COMMIT; -- may raise a serialization_failure you retry이상 현상 행렬
가장 유용하게 외워 둘 내용은 각 수준에서 어떤 이상 현상을 허용하는지입니다. "예"는 해당 이상 현상이 발생할 수 있다는 뜻입니다.
- READ UNCOMMITTED: 더티=예, 비반복=예, 팬텀=예
- READ COMMITTED: 더티=아니요, 비반복=예, 팬텀=예
- REPEATABLE READ: 더티=아니요, 비반복=아니요, 팬텀=예(표준상)
- SERIALIZABLE: 더티=아니요, 비반복=아니요, 팬텀=아니요
한 단계 올라갈 때마다 이상 현상을 하나씩 더 금지합니다. 이 진행 과정이 답변의 전부입니다.
표준과 실제 구현
고급 면접에서 구분해야 할 점은 다음과 같습니다. 표준은 방법이 아니라 어떤 이상 현상을 반드시 방지해야 하는지를 기준으로 수준을 정의합니다. 실제 엔진은 그보다 더 많은 현상을 방지하는 경우가 많습니다.
- PostgreSQL REPEATABLE READ는 스냅샷 격리를 사용하여 팬텀도 차단하지만, 쓰기 편향은 여전히 발생할 수 있습니다.
- MySQL/InnoDB REPEATABLE READ는 다음 키 잠금으로 팬텀을 차단합니다.
- PostgreSQL SERIALIZABLE은 SSI(직렬화 가능한 스냅샷 격리)를 사용하여 강한 잠금 대신 충돌이 발생하면 트랜잭션을 중단합니다.
이 내용을 언급하면 표준이 정확한 동작을 정의한 것이 아니라 최소 기준을 정한다는 점을 알고 있음을 보여 줄 수 있습니다.
엔진별 기본 수준
기본값은 면접에서 매우 자주 나옵니다. 다음 내용을 외워 두십시오.
- PostgreSQL: READ COMMITTED
- 오라클: READ COMMITTED(더티 리드는 항상 발생하지 않음)
- 에스큐엘 서버: READ COMMITTED
- MySQL (InnoDB): REPEATABLE READ
MySQL의 예외적인 기본값은 면접에서 자주 나오는 함정입니다. "기본 격리 수준이 무엇인가요?"라는 질문을 받으면 항상 먼저 엔진을 확인하십시오.
실무에서 수준 선택하기
어떻게 결정해야 할까요? 위험과 처리량의 관점에서 생각하십시오.
- 일반적인 OLTP에는 READ COMMITTED를 사용하십시오. 빠르고 더티 리드를 방지합니다.
- 트랜잭션이 같은 데이터를 여러 번 읽으며 값이 안정적으로 유지되어야 할 때는 REPEATABLE READ를 사용하십시오(보고서, 여러 단계의 계산).
- 어떤 이상 현상도 허용할 수 없는 정확성 중심의 논리에는 SERIALIZABLE을 사용하고, 중단에 대비한 재시도 논리를 설계하십시오.
운영 환경에서는 READ UNCOMMITTED를 거의 사용하지 마십시오.
자주 나오는 후속 질문
수준을 나열하고 나면 면접관은 빠른 후속 질문으로 더 깊이 확인합니다. 다음과 같이 간결하게 답할 준비를 하십시오.
- "더티 리드를 방지하면서 비반복 읽기를 허용하는 수준은 무엇인가요?" READ COMMITTED입니다.
- "표준상 REPEATABLE READ가 여전히 허용하는 유일한 이상 현상은 무엇인가요?" 팬텀 읽기입니다.
- "항상 SERIALIZABLE을 사용하면 안 되나요?" 동시성이 낮아지고 직렬화 실패가 발생하면 트랜잭션을 재시도해야 할 수 있기 때문입니다.
- "더 높은 수준은 비용이 더 많이 드나요?" 그렇습니다. 잠금 비용이나 중단 후 재시도에 따른 부담이 커집니다.
이 질문들에 즉시 답할 수 있다면 단계 구조를 암기가 아니라 이해하고 있다는 것을 보여 줄 수 있습니다.
빠른 확인
다음 중 기본 격리 수준에 관해 가장 자주 확인하는 사실이 하나 있습니다.
복습: 네 가지 수준과 하나의 상충 관계
네 가지 격리 수준은 가장 약한 수준부터 가장 강한 수준까지 다음과 같은 단계 구조를 이룹니다. READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE입니다. 한 단계 올라갈 때마다 동시성을 낮추는 대신 이상 현상(더티, 비반복, 팬텀)을 하나씩 더 금지합니다.
MySQL의 REPEATABLE READ를 제외하면 어디서나 READ COMMITTED가 기본값이라는 점을 기억하고, 실제 엔진은 표준이 요구하는 것보다 더 많은 현상을 방지하는 경우가 많다는 점도 기억하십시오. 다음에는 이 수준들이 방지하도록 설계된 세 가지 읽기 이상 현상을 살펴봅니다.
자주 묻는 질문
“네 가지 격리 수준” 강의는 무료인가요?
네 — “네 가지 격리 수준” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Coding Interview Prep 강의 전체를 잠금 해제할 수 있습니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
“네 가지 격리 수준”에서 뭘 배우나요?
커밋되지 않은 읽기부터 직렬화 가능 수준까지, 각 수준에서 허용되는 동작을 알아봅니다. 브라우저에서 직접 실행하는 실습 코드로 Coding Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Coding Interview Prep을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Coding Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“네 가지 격리 수준” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Coding Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Coding Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.