더티 리드, 반복 불가능 읽기, 팬텀 리드
세 가지 읽기 이상 현상과 각각을 막는 격리 수준을 알아봅니다.
더티 리드, 반복 불가능 읽기, 팬텀 리드은(는) CoddyKit의 무료 Coding Interview Prep 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Coding Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
세 가지 읽기 이상 현상
격리 수준은 읽기 이상 현상이라고 하는 특정 동시성 버그를 방지하기 위해 존재합니다. 면접관은 세 가지를 모두 정확하게 정의하고 각각을 방지하는 수준과 연결할 수 있는지 기대합니다.
- 더티 리드 - 확정되지 않은 데이터 읽기
- 비반복 읽기 - 두 번 읽는 사이에 행이 변경됨
- 팬텀 리드 - 두 번 읽는 사이에 새 행이 나타남
어려운 점은 비반복 읽기와 팬텀 리드를 구분하는 것입니다. 둘 다 다시 질의했을 때 다른 결과를 얻는 경우이기 때문입니다.
더티 리드: 정의
더티 리드는 트랜잭션 T1이 트랜잭션 T2가 변경했지만 아직 확정하지 않은 행을 읽을 때 발생합니다. 이후 T2가 되돌리면 T1은 실제로는 존재한 적이 없는 데이터를 바탕으로 작업한 셈이 됩니다.
READ UNCOMMITTED만 더티 리드를 허용합니다. 그보다 높은 모든 수준에서는 더티 리드를 금지합니다.
실제 위험: 몇 초 뒤 되돌려질 예금을 근거로 대출을 승인하는 경우입니다.
더티 리드: 시간 순서
두 열을 시간 순서로 읽어 보십시오. T1은 READ UNCOMMITTED에서 실행 중입니다.
T1은 잔액 700을 보지만 T2는 끝내 확정하지 않습니다. 700은 T2가 진행 중인 작업에서 나타난 유령 값이었습니다. T2가 되돌린 뒤 실제 값은 여전히 500입니다. T1은 잘못된 데이터를 바탕으로 결정을 내렸습니다.
-- T2 (not committed) | -- T1 (READ UNCOMMITTED)
BEGIN; |
UPDATE accounts |
SET balance = 700 |
WHERE id = 1; |
| SELECT balance FROM accounts
| WHERE id = 1; -- reads 700 (dirty!)
ROLLBACK; |
| -- T1 acted on a value that never existed비반복 읽기: 정의
비반복 읽기는 T1이 행을 읽은 뒤 T2가 같은 행을 확정된 상태로 갱신하거나 삭제하고, T1이 그 행을 다시 읽었을 때 다른 값을 보게 되는 경우입니다.
더티 리드와의 핵심적인 차이에 주목하십시오. 여기서는 T2가 확정했습니다. 데이터 자체는 실제이지만, 하나의 트랜잭션 안에서 T1이 작업하는 동안 데이터가 변경된 것입니다.
READ COMMITTED에서는 여전히 이 현상이 발생할 수 있습니다. REPEATABLE READ 이상에서는 안정적인 스냅샷에서 읽기 때문에 이를 방지합니다.
비반복 읽기: 시간 순서
T1은 READ COMMITTED에서 실행되며 같은 행을 두 번 읽습니다. 두 번 읽는 사이에 T2가 변경 사항을 확정합니다.
하나의 트랜잭션 안에서 같은 기본 키가 서로 다른 두 값을 반환합니다. 이러한 불일치는 행이 변하지 않는다고 가정하는 여러 단계의 로직을 깨뜨릴 수 있습니다.
-- T1 (READ COMMITTED) | -- T2
BEGIN; |
SELECT balance FROM accounts |
WHERE id = 1; -- 500 |
| BEGIN;
| UPDATE accounts SET balance = 900
| WHERE id = 1;
| COMMIT;
SELECT balance FROM accounts |
WHERE id = 1; -- 900 (changed!) |
COMMIT; |팬텀 리드: 정의
팬텀 리드는 T1이 검색 조건이 있는 질의를 실행하고, T2가 그 조건에 맞는 행을 확정된 상태로 INSERT(또는 DELETE)한 뒤, T1이 질의를 다시 실행했을 때 다른 행 집합을 보게 되는 경우입니다.
비반복 읽기와의 차이는 다음과 같습니다. 비반복 읽기는 기존 행의 값이 변경되는 것이고, 팬텀 리드는 술어에 맞는 행의 수가 변경되는 것입니다.
표준에서 팬텀 리드를 방지한다고 보장하는 수준은 SERIALIZABLE뿐입니다.
팬텀 리드: 시간 순서
T1은 값이 큰 계정을 두 번 셉니다. 두 번 세는 사이에 T2가 조건에 맞는 새 행을 삽입하고 확정합니다.
기존 행은 하나도 변경되지 않았지만 COUNT 결과는 달라집니다. 새 행이 T1의 결과 집합에 나타난 "유령"입니다.
-- T1 (REPEATABLE READ, standard) | -- T2
BEGIN; |
SELECT COUNT(*) FROM accounts |
WHERE balance > 1000; -- 3 |
| INSERT INTO accounts(id, balance)
| VALUES (99, 5000);
| COMMIT;
SELECT COUNT(*) FROM accounts |
WHERE balance > 1000; -- 4 (phantom)|
COMMIT; |이상 현상과 수준의 연결
이 연결이 이 주제의 핵심입니다. 각 이상 현상을 방지하는 가장 낮은 수준은 다음과 같습니다.
- 더티 리드는
READ COMMITTED이상에서 방지됩니다. - 비반복 읽기는
REPEATABLE READ이상에서 방지됩니다. - 팬텀 리드는
SERIALIZABLE에서 방지됩니다(표준 기준).
이름도 의미에 맞습니다. REPEATABLE READ는 읽기를 반복 가능하게 만들며, 각 수준은 새로 해결하는 이상 현상의 이름을 따서 명명되었습니다.
비반복 읽기와 팬텀 리드: 명확한 구분
면접에서 가장 흔히 혼동하는 부분입니다. 다음 한 문장을 기억하십시오.
비반복 읽기 = 기존 행의 값이 변경됨. 팬텀 리드 = 조건에 맞는 행 집합이 변경됨(행이 추가되거나 제거됨).
스스로 확인해 보십시오. T2가 UPDATE ... WHERE id = 5를 실행한 뒤 확정하고, T1이 행 5를 다시 읽는다면 비반복 읽기입니다. T2가 T1의 WHERE 조건에 맞는 새 행을 INSERT하고 T1이 질의를 다시 실행한다면 팬텀 리드입니다.
쓰기 편향: 추가 이상 현상
경력직 면접에서는 세 가지 표준 이상 현상을 넘어 쓰기 편향까지 질문할 수 있습니다. 두 트랜잭션이 서로 겹치는 집합을 각각 읽고, 읽은 내용에 따라 서로 겹치지 않는 쓰기를 수행한 뒤 모두 확정하여, 어느 한 트랜잭션만 실행했더라면 허용하지 않았을 상태를 남기는 현상입니다.
대표적인 예는 두 의사가 당직 중인 경우입니다. 각 의사가 다른 의사가 당직 중인지 확인한 뒤 자신은 당직에서 빠집니다. 둘 다 성공하면 당직자가 한 명도 남지 않습니다.
스냅샷 격리(포스트그레스의 REPEATABLE READ)에서는 쓰기 편향이 허용되며, 이를 막는 것은 SERIALIZABLE뿐입니다. 이 점을 언급하면 깊이 있는 이해를 보여줄 수 있습니다.
갱신 손실: 네 번째 함정
면접관은 표준의 이상 현상 목록에는 없지만 실무에서 매우 흔한 갱신 손실을 일부러 질문하기도 합니다. 두 트랜잭션이 같은 값을 읽고, 그 값을 바탕으로 새 값을 계산한 다음, 둘 다 결과를 기록합니다. 나중에 기록한 쪽이 먼저 기록한 값을 조용히 덮어씁니다.
예를 들어 두 이체 작업이 각각 잔액 500을 읽고, 각자 금액을 차감한 뒤 결과를 기록하면 한 번의 차감이 사라집니다.
해결책은 단순히 더 높은 격리 수준을 사용하는 것이 아니라, SELECT ... FOR UPDATE를 사용한 명시적 잠금이나 애플리케이션이 아니라 데이터베이스에서 계산하는 원자적 갱신을 사용하는 것입니다.
-- Safe pattern: lock the row, or compute atomically
BEGIN;
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE; -- locks row
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;
-- Or simply: UPDATE accounts SET balance = balance - 100 WHERE id = 1;빠른 확인
동작을 보고 이상 현상을 식별해 보십시오.
복습: 이상 현상과 해결 수준
세 가지 읽기 이상 현상은 각각 더 높은 격리 수준에서 해결됩니다.
- 더티 리드(확정되지 않은 데이터) - READ COMMITTED에서 해결됩니다.
- 비반복 읽기(기존 행의 값이 변경됨) - REPEATABLE READ에서 해결됩니다.
- 팬텀 리드(조건에 맞는 행 집합이 변경됨) - SERIALIZABLE에서 해결됩니다.
비반복 읽기와 팬텀 리드를 명확히 구분하고, 면접관이 더 깊은 답을 원하면 쓰기 편향도 언급하십시오. 다음으로는 데이터베이스 엔진이 실제로 격리를 구현하는 방법인 잠금, 교착 상태, MVCC를 살펴봅니다.
AI 튜터와 함께 Coding Interview Prep을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 90
- 레슨
- 360
자주 묻는 질문
“더티 리드, 반복 불가능 읽기, 팬텀 리드” 강의는 무료인가요?
네 — “더티 리드, 반복 불가능 읽기, 팬텀 리드” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 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개 중 3번째 강의입니다.
“더티 리드, 반복 불가능 읽기, 팬텀 리드” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Coding Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Coding Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- ACID 속성 설명
- 네 가지 격리 수준
- 더티 리드, 반복 불가능 읽기, 팬텀 리드
- 교착 상태, 잠금, MVCC