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 → Ablocking입니다. 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를 가리키므로, 그 값 하나만으로 전체 요청 간 순환을 보여 주지는 않습니다.

SQL Server 2022 DMV를 읽는 참고 쿼리입니다. 서버에 연결해 실행하지 않았습니다.
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, 다시 순환으로 갑니다

  1. 대기 중인 세션의 session_id, status, wait_type, wait_resource와 blocking_session_id를 기록합니다.
  2. blocker 세션의 현재 요청과 열린 트랜잭션을 확인해 대기 사슬의 시작점을 찾습니다.
  3. 관련 세션들이 각각 어떤 자원을 보유하고 어떤 자원을 요청하는지 연결합니다.
  4. 그래프가 처음 요청으로 되돌아오는지 확인하고, victim 종료 오류나 deadlock graph가 기록됐는지 별도로 확인합니다.
  5. 순환이 없으면 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 값 한 개는 전체 그래프를 대신하지 않습니다.