Blocking은 한 세션이 다른 세션이 가진 자원을 기다리는 상태입니다. Deadlock은 둘 이상의 작업이 서로가 가진 자원을 기다려 의존 관계에 순환이 생긴 상태입니다.
오래 기다렸다는 사실이나 DMV의 blocker 한 칸만으로 deadlock을 확정할 수 없습니다. 대기 그래프의 순환과 Database Engine이 victim을 종료한 흔적을 확인해야 합니다.
긴 대기는 현상이고 deadlock은 순환 의존입니다
SQL Server에서 blocking은 요청한 세션이 다른 세션이 잠근 자원을 얻지 못해 기다리는 상태입니다. 자원을 가진 세션이 끝나 잠금을 놓으면 기다리던 세션은 계속 실행할 수 있습니다. 이 대기는 길어질 수 있고, 기본 설정에서는 LOCK_TIMEOUT을 지정하지 않은 트랜잭션이 자동으로 짧은 시간 뒤 끝난다고 볼 수 없습니다. 긴 대기만으로 서로가 서로를 막는 deadlock이라고 판단해서는 안 됩니다.
Deadlock은 두 개 이상의 작업이 각자 보유한 자원을 내놓지 못하면서 상대가 가진 자원을 기다리는 순환 의존입니다. 예를 들어 A가 상품 행을 잠근 뒤 주문 행을 기다리고, B가 주문 행을 잠근 뒤 상품 행을 기다리면 A→B→A 고리가 생깁니다. 누구도 다음 단계로 가지 못하므로 Database Engine의 deadlock monitor가 고리를 찾아 한 트랜잭션을 victim으로 종료하고 오류를 반환해 다른 작업이 계속하도록 합니다.
세션 그래프에 화살표를 그려 순환을 확인합니다
| 상황 | 보유 자원 | 기다리는 자원 | 의존 그래프 | 판정 |
|---|---|---|---|---|
| 단방향 대기 | A가 행 R1 보유 | B가 R1을 기다림 | B → A | blocking입니다. A가 끝나면 B가 진행할 수 있습니다. |
| 서로 기다림 | A가 R1, B가 R2 보유 | A는 R2, B는 R1 대기 | A → B → A | 순환이므로 deadlock 조건에 해당합니다. |
| 긴 단방향 대기 | A가 R1을 오래 보유 | B가 R1을 기다림 | B → A | 대기 시간이 길어도 그래프만 보면 순환은 없습니다. |
그래프의 화살표는 '요청 세션이 blocker를 기다린다'는 방향으로 그렸습니다. 먼저 기다리는 요청에서 시작해 누가 자원을 잡고 있는지 따라갑니다. 화살표가 blocker를 거쳐 다시 처음 요청으로 돌아오면 순환입니다. 한 방향으로 끝나는 사슬이면 정상 blocking이며, 맨 앞에서 여러 세션을 막는 head blocker를 찾는 일이 우선입니다. 종료 후에는 다음 세션이 차례로 진행할 수 있습니다.
DMV 값은 대기 단서이고 순환 증명은 따로 확인합니다
현재 요청 조회 결과에는 status, blocking_session_id, wait_type, wait_time, wait_resource 등이 있습니다. 이 값은 '누가 기다리는지, 누구를 blocker로 보는지, 어떤 자원과 대기 종류가 보이는지'를 좁히는 단서입니다. Microsoft는 공식 DMV 문서에서 이 필드들을 현재 실행 중인 요청의 정보로 설명합니다. 한 행의 blocking_session_id는 한 요청의 blocker를 가리키므로, 그 값 하나만으로 전체 요청 간 순환을 보여 주지는 않습니다.
SELECT session_id, status, blocking_session_id,
wait_type, wait_time, wait_resource
FROM sys.dm_exec_requests
WHERE status = N'suspended';이 쿼리는 suspended 요청의 일부 값을 보는 읽기 예시일 뿐 deadlock 탐지기가 아닙니다. 대기 종류가 lock인지 확인하고, 관련 요청을 시간상 함께 모아 의존 그래프를 구성해야 합니다. 병렬 요청은 한 요청 안에서도 여러 task가 서로 다른 자원을 기다릴 수 있습니다. 또 SQL Server 2022에서 서버 전체 DMV를 보려면 VIEW SERVER PERFORMANCE STATE 권한이 필요할 수 있으므로 권한 범위도 고려해야 합니다. 실제 운영 환경에서는 Microsoft가 설명하는 deadlock 보고서나 Extended Events 등 별도 기록을 함께 확인합니다.
조사 순서는 대기 요청에서 head blocker, 다시 순환으로 갑니다
- 대기 중인 세션의 session_id, status, wait_type, wait_resource와 blocking_session_id를 기록합니다.
- blocker 세션의 현재 요청과 열린 트랜잭션을 확인해 대기 사슬의 시작점을 찾습니다.
- 관련 세션들이 각각 어떤 자원을 보유하고 어떤 자원을 요청하는지 연결합니다.
- 그래프가 처음 요청으로 되돌아오는지 확인하고, victim 종료 오류나 deadlock graph가 기록됐는지 별도로 확인합니다.
- 순환이 없으면 deadlock 대신 오래 열린 트랜잭션이나 head blocker 등 확인된 상태를 보고합니다.
흔한 실수는 화면에 'suspended'가 보이거나 wait_time 값이 크다는 이유로 deadlock이라고 이름 붙이는 것입니다. suspended는 현재 요청 상태이지 교착 여부의 판정 결과가 아닙니다. blocker가 0 또는 NULL이면 현재 대기 요청이 없거나 blocker 정보를 확인하지 못했다는 뜻일 수 있습니다. 값을 한 줄만 보고 단정하지 말고, 여러 세션의 자원 보유·요청 관계와 종료 기록을 함께 보세요.
정답을 가리고 두 그래프의 이름을 붙여 보세요
세션 A가 R1을 보유하고 세션 B가 R2를 보유합니다. A는 R2를 요청하고 B는 R1을 요청합니다. 그래프는 A→B→A로 돌아오므로 deadlock 조건에 해당합니다. 반면 B만 A를 기다리고 A가 아무 세션도 기다리지 않는다면 단방향 blocking입니다. DMV에서 B가 A를 blocker로 가리키는 행 하나만 본 상태라면 아직 둘 중 어느 구조인지 확정할 수 없습니다. A의 요청과 보유 자원까지 이어서 조사해야 답을 낼 수 있습니다.
정답을 가리고 확인해 보세요
이 글을 위해 만든 학습 예시이며 공식 기출문제나 판매 카드의 인용이 아닙니다.
SQL Server 요청 한 건이 session 52를 기다리고 90초 동안 suspended였습니다. 이 정보만으로 deadlock이라고 판정할 수 있나요?
정답과 해설 확인
아니요. 현재는 blocking 증거입니다. 다른 세션이 다시 첫 요청을 기다리는 순환인지 추가로 확인해야 합니다.긴 대기는 한 방향으로 지속될 수 있습니다. deadlock은 서로 가진 자원을 기다리는 순환 의존이며, DMV의 blocker 값 한 개는 전체 그래프를 대신하지 않습니다.