[LG U+ 유레카 3기] Deadlock & 2단계 로킹 실습

2025. 10. 16. 14:49DB

DeadLock

이번 실습에서는 MySQL데드락(Deadlock) 현상을 직접 재현하고, 이 과정이 내부적으로 2단계 로킹(2PL, Two-Phase Locking) 프로토콜 위에서 동작한다는 사실을 함께 확인했습니다.

---

❶ 상황 설명

두 개의 세션(Session 1, Session 2)이 같은 테이블 book의 서로 다른 행을 서로 다른 순서로 UPDATE 하며, 교착 상태(Deadlock)를 유발하도록 실험했습니다.

---

❷ 실습 코드

Session 1

START TRANSACTION;
UPDATE book SET price = 8000 WHERE bookid = 2;
UPDATE book SET price = 8000 WHERE bookid = 1;
COMMIT;

Session 2

START TRANSACTION;
UPDATE book SET price = 8000 WHERE bookid = 1;
UPDATE book SET price = 8000 WHERE bookid = 2;
COMMIT;

두 세션이 서로 반대 순서로 락을 획득하려고 시도하면서 교착 상태가 발생합니다.

---

❸ 실습 화면

output 확인
output 확인

하단 Action Output 로그를 보면, 한쪽 트랜잭션(Session 2)에서 Error Code: 1213. Deadlock found when trying to get lock 메시지가 발생한 것을 확인할 수 있습니다.

---

❹ Deadlock 발생 원리

InnoDB는 내부적으로 2단계 로킹(2PL, Two-Phase Locking) 프로토콜을 사용합니다. 즉, 트랜잭션은 “락을 걸 수 있는 단계(확장 단계)”와 “락을 해제만 하는 단계(축소 단계)”를 명확히 구분합니다.

단계 이름 동작
1️⃣ 확장 단계 (Growing Phase) 락 획득만 가능, 해제 불가
2️⃣ 축소 단계 (Shrinking Phase) 락 해제만 가능, 새 락 획득 불가

이번 실습에서 두 트랜잭션은 모두 확장 단계에서 서로 다른 행에 배타 락(Exclusive Lock, X-lock)을 걸고, 상대가 가진 락을 기다리면서 2PL 구조에서의 전형적인 Deadlock이 발생했습니다.

---

❺ 어떤 트랜잭션이 예외를 받는가?

MySQL InnoDB는 내부 알고리즘을 통해 잠금(lock)을 더 적게 보유한 트랜잭션을 희생시킵니다.
즉, 영향을 받는 rows 수가 적은 트랜잭션에서 Deadlock Error (Error Code: 1213)가 발생합니다.

---

❻ Deadlock 해결 전략

  • 항상 락을 획득하는 순서를 일관되게 유지한다.
  • 가능하면 트랜잭션의 크기를 작게 유지한다.
  • Deadlock은 DBMS의 동시성 제어(Concurrency Control) 과정에서 자연스러운 현상임을 인지한다.
  • 에러가 발생했을 경우 ROLLBACK 후 재시도하는 로직을 구현한다.

---

❼ 핵심 요약

개념 내용
2단계 로킹 (2PL) 락 획득 단계와 해제 단계가 분리되어 일관성 보장
Deadlock 서로의 락을 기다리며 트랜잭션이 교착 상태에 빠지는 현상
InnoDB 대응 방식 가장 적은 Row를 잠근 트랜잭션을 중단(Error 1213)
해결법 락 순서 일관성 유지, 트랜잭션 최소화, 재시도 로직 구현

---

❽ 교훈 및 요약 문장

이번 실습을 통해 MySQL의 Deadlock은 2단계 락킹 구조 안에서 자연스럽게 발생하며, DBMS는 트랜잭션의 직렬성을 유지하기 위해 덜 영향이 큰 트랜잭션을 중단시키는 것을 확인했습니다.
즉, Deadlock은 피해야 할 오류가 아니라, 동시성 제어의 일부 과정이라는 점을 이해하는 것이 핵심입니다.