1. DMV 활용 (추천)
SQL
-- 현재 잠금 상태 확인
SELECT
tl.resource_type,
tl.resource_database_id,
tl.resource_associated_entity_id AS TableObjectId,
tl.request_mode,
tl.request_status,
r.session_id,
s.login_name,
s.host_name,
r.blocking_session_id,
r.command,
r.status,
r.wait_type,
r.wait_time,
r.wait_resource
FROM sys.dm_tran_locks AS tl
JOIN sys.dm_exec_requests AS r
ON tl.request_session_id = r.session_id
JOIN sys.dm_exec_sessions AS s
ON r.session_id = s.session_id
WHERE tl.resource_type <> 'DATABASE';
- resource_associated_entity_id → 테이블 ObjectId (매핑하려면 OBJECT_NAME() 사용)
- request_mode → 잠금 모드 (X = Exclusive, S = Shared 등)
- blocking_session_id → 어떤 세션이 다른 세션을 막고 있는지 확인 가능
2. 시스템 프로시저 활용
- EXEC sp_who2; → BlkBy 컬럼에 값이 있으면 해당 세션이 다른 세션을 막고 있음
- EXEC sp_lock; → 잠금 상태 확인 (구버전 방식, 여전히 유용)
- SELECT * FROM sys.sysprocesses WHERE blocked > 0; → 블로킹된 프로세스 확인
3. 문제 세션 추적 및 종료
특정 세션 ID(spid)를 찾았다면, 해당 쿼리 내용을 확인:
SQL
DBCC INPUTBUFFER(<spid>);→ 어떤 SQL 문장이 잠금을 걸고 있는지 확인 가능
필요하다면 강제로 종료:
SQL
KILL <spid>;⚠️ 주의사항
- 무조건 KILL은 최후 수단: 트랜잭션 중인 세션을 종료하면 데이터 불일치나 롤백 비용이 발생할 수 있음.
- 원인 파악 우선: 장시간 실행되는 트랜잭션, 인덱스 없는 대량 업데이트, 불필요한 BEGIN TRAN 유지 등이 원인일 수 있음.