단순한 데드락 사례
앞장의 데드락 분석 방법에 대한 설명에 이어 이번에는 단순한 데드락 사례를 들어 보자.
두개의 테이블 TabA, TabB가 있다고 가정하고, 이 테이블들을 하나의 트랙잭션에 UPDATE한다고 가정하자.
그런데 한 세션(SPID 55)에서는 TabA를 먼저 Update하고 TabB를 나중에 Update하고, 다른 세션(SPID 56)에서는 TabB를 먼저 Update하고
나중에 TabA를 Update한다고 하자. 이 사례는 전형적인 데드락 케이스로서 SPID 55는 TabA에 대해 X (Exclusive) Lock을 가지고 있고,
SPID 56는 TabB에 대해 X Lock을 각각 소유하고 있다. 그런데, 다음 문장이 SPID 55는 SPID 56가 소유하고 있는 TabB에 대해 X Lock을 획득해야 하는데,
이는 이미 SPID 56가 소유하고 있으므로, 이 X Lock이 56에 의해 해제 되기를 기다린다. 반면 SPID 56는 TabA에 대해 X Lock을 가져야 하는데,
이는 이미 SPID 55가 소유하고 있으므로 이 리소스가 해제 될 때까지 기다린다. 따라서 Dead Lock이 발생하여 SQL 엔진은 그 중 하나인 SPID 56를 종료한다.
그런데, 왜 SQL 엔진은 55가 아닌 56을 Kill 했을까? 이는 아래 그래프에서 타원형 SPID 정보 중 Log Used 값을 비교해 보면 알 수 있다.
SPID 55는 Log Used가 264이고 SPID 56는 260이다. 따라서 SQL 엔진은 SPID 55가 더 많이 작업을 진행했다고 보고 56을 Kill 한 것이다.
해결 방안
위의 사례에 대한 해결 방법은 테이블 UPDATE시 동일한 순서로 갱신하는 것이다.
위 사례의 경우, 한 세션은 UPDATE A를 한 후 UPDATE B를 하고, 다른 세션은 UPDATE B 를 한후 UPDATE A를 한다.
이를 해결하기 위해서는 두 세션 모두 - 이것이 로직상 가능하다면 - UPDATE A를 먼저 하고, 다음 UPDATE B를 하는 것이다.
본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.