Deadlock이란? 여러 작업이 서로 기다리다가 멈추는 교착 상태 쉽게 이해하기
Deadlock은 여러 작업이 서로 상대 자원을 기다리며 아무도 진행하지 못하는 교착 상태입니다. Lock Ordering·Coffman·DB Victim·Retry·Contention·Livelock·Starvation까지 초보 기준으로 정리합니다.
좁은 골목 · Circular Wait
Race Condition을 막으려 Lock을 쓰면, A가 Lock 1을 잡고 Lock 2를 기다리고 B가 Lock 2를 잡고 Lock 1을 기다리는 식으로 서로가 상대를 기다리며 아무도 진행하지 못하는 상태가 될 수 있습니다. 이것이 Deadlock(교착 상태)입니다. 좁은 골목에서 두 차가 「저쪽이 먼저 빠지겠지」만 기다리는 것과 같습니다. 단순 Lock 대기(앞 작업이 끝나면 진행)나 느린 쿼리(결국 끝남)와 다릅니다. Coffman 조건으로 자주 설명합니다 — Mutual Exclusion(한 번에 한 작업만), Hold and Wait(가진 채 추가 대기), No Preemption(강제 회수 불가), Circular Wait(원형으로 서로 기다림).
A: Lock1 보유 → Lock2 대기 B: Lock2 보유 → Lock1 대기 → Circular Wait → 진행 불가
DB · Lock Ordering · Victim · Retry
계좌 이체처럼 T1이 A→B, T2가 B→A 순으로 Row Lock을 잡으면 Deadlock이 납니다. 예방의 핵심은 Lock Ordering — 예: Account ID가 작은 것부터 항상 같은 순서. Table Lock보다 Row Lock이 동시성에는 유리하지만, 여러 Row를 엇갈린 순서로 잠그면 같은 구조의 Deadlock이 납니다. 많은 DB는 Deadlock을 감지해 Transaction 하나를 Deadlock Victim으로 Rollback해 순환을 끊습니다. 앱에는 오류로 보이며 일시적이면 제한 Retry·Backoff·Jitter가 도움이 됩니다. 근본 원인이 같은 반대 순서라면 무한 Retry는 부하만 키웁니다. Lock Wait Timeout은 「오래 기다림」이지 반드시 Deadlock은 아닙니다. Transaction 안에서 외부 API·사용자 확인을 기다리면 Lock이 길어져 Contention·Timeout 위험이 커집니다 — DB 작업 구간만 짧게 유지하세요.
예방 · Contention · Livelock · Starvation
예방 체크: Lock 순서 통일, Lock 짧게, 불필요 Lock 축소, Transaction을 원자성 범위 안에서만 작게, 인덱스·쿼리로 잠금 범위·시간 축소. Global Lock 하나로 순환을 없애면 동시성이 크게 떨어집니다. Lock Contention은 기다리다가 결국 진행되고, Deadlock은 순환으로 진행 불가입니다. Hotspot(인기 상품·공통 카운터)에서는 경쟁이 심해집니다. Mutex·Semaphore·파일 Lock·분산 Lock에서도 순환 대기가 생기면 Deadlock입니다. 분산 Lock의 TTL은 장애 시 Lock 잔존을 줄이지만, 작업이 TTL보다 길면 이중 처리 위험이 있어 Fencing Token 같은 기법이 등장합니다. Livelock은 계속 움직이지만 양보만 반복해 진전이 없고, Starvation은 시스템은 도는데 특정 작업만 계속 기회를 못 얻는 상태입니다. 증상은 지연·주문 실패·간헐 500으로 보일 수 있어 로그·Wait-for Graph·분산 추적이 원인 추적에 도움이 됩니다. Retry 시에는 작업의 멱등성도 함께 확인합니다.
Deadlock: 서로 기다림 → 멈춤 Contention: 기다림 → 앞 작업 끝나면 진행 Livelock: 움직임 → 진전 없음 Starvation: 시스템은 진행 → 특정 작업만 계속 밀림
자주 묻는 질문
Deadlock이란?
여러 작업이 서로 상대 자원을 기다리며 아무도 진행하지 못하는 교착 상태입니다.
Lock 대기는 모두 Deadlock인가요?
아닙니다. 앞 작업이 끝나면 진행되면 단순 대기입니다. 순환으로 진행 불가일 때 Deadlock입니다.
Race Condition과 차이는?
Race는 잘못된 결과가 생기는 문제, Deadlock은 서로를 기다려 결과를 못 만드는 문제입니다. Race Condition 가이드를 참고하세요.
DB가 자동으로 풀나요?
많은 DB는 감지 후 한쪽 Transaction을 Rollback합니다. 제품마다 정책이 다를 수 있습니다.
Retry해도 되나요?
일시적이면 제한 Retry가 가능합니다. 자주 나면 Lock 순서·Transaction 구조를 먼저 고칩니다.
예방의 쉬운 방법은?
여러 자원을 잠글 때 모든 코드가 같은 Lock 순서를 쓰도록 통일하는 것입니다.
정리
Deadlock = 서로 상대 자원을 기다리며 아무도 진행하지 못하는 교착 상태입니다. A는 Lock1을 잡고 Lock2를, B는 Lock2를 잡고 Lock1을 기다리는 그림으로 기억하면 됩니다. Lock Ordering·짧은 Transaction·불필요 Lock 축소·쿼리/인덱스·제한 Retry로 줄입니다. Deadlock은 「모두 멈춤」인데, 시스템 전체는 도는데 특정 작업만 계속 실행 기회를 못 얻어 무기한 기다리는 현상도 있습니다 — 이것이 Starvation(기아 상태)입니다.