CS지식/데이터베이스 (Database)
(데이터베이스) Lock, Two-Phase Locking(2PL), 데드락 정리(예제 포함)
불광동 물주먹
2025. 5. 21. 00:28
데이터베이스 Lock과 2PL, 데드락까지 완벽 정리
동시성을 제어하는 건 단순히 commit을 잘하는 걸 넘어서, **일관성, 격리성(ACID 중 I)**을 유지하는 핵심 기술입니다. 이 포스팅에선 Read/Write Lock, 2PL, 데드락, 그리고 MVCC까지 단계적으로 정리해봅니다.
📌 1. Lock 호환성 (Lock Compatibility)
DB는 트랜잭션 간의 충돌을 막기 위해 Lock을 사용합니다.
read-lock | write-lock | |
read-lock | ✅ 가능 | ❌ 불가능 |
write-lock | ❌ 불가능 | ❌ 불가능 |
- read-lock (공유 잠금):
- 다른 트랜잭션이 읽는 것은 가능, 쓰는 것은 불가
- 여러 트랜잭션이 동시에 읽는 것 가능
- write-lock (배타 잠금):
- 읽기/쓰기 둘 다 막음
- 오직 단일 트랜잭션만 접근 가능
📌 2. Lock 시나리오 예시
✅ 시나리오 1: 두 트랜잭션이 동시에 같은 데이터를 읽을 때
-- Tx1
BEGIN;
SELECT * FROM accounts WHERE id = 1; -- read-lock 획득
-- Tx2
BEGIN;
SELECT * FROM accounts WHERE id = 1; -- read-lock 가능 (공유)
✔ 문제 없이 동시 수행 가능
❌ 시나리오 2: 읽기 중 누군가가 쓰려고 할 때
-- Tx1
BEGIN;
SELECT * FROM accounts WHERE id = 1; -- read-lock
-- Tx2
BEGIN;
UPDATE accounts SET balance = 1000 WHERE id = 1; -- write-lock 시도 → 대기
🛑 Tx2는 Tx1의 read-lock이 해제될 때까지 대기
(락 경합 발생)
❌ 시나리오 3: 쓰기 중 다른 트랜잭션이 읽거나 쓰려고 할 때
-- Tx1
BEGIN;
UPDATE accounts SET balance = 1000 WHERE id = 1; -- write-lock
-- Tx2
BEGIN;
SELECT * FROM accounts WHERE id = 1; -- read-lock 시도 → 대기
-- Tx3
UPDATE accounts SET balance = 2000 WHERE id = 1; -- write-lock 시도 → 대기
🛑 둘 다 write-lock 해제 전까지 대기
→ write-lock은 모든 접근을 차단
📌 3. Two-Phase Locking (2PL)
트랜잭션이 serializable 스케줄을 따르기 위한 기본 원칙.
구조
- 확장 단계 (Expanding Phase)
- Lock만 획득. 해제는 금지.
- 축소 단계 (Shrinking Phase)
- Lock 해제만 가능. 새 Lock 획득 금지.
Tx1: Lock(A) → Lock(B) → Unlock(A) → Unlock(B) ✅ 2PL
Tx2: Lock(A) → Unlock(A) → Lock(B) ❌ 2PL 위반
📌 4. 데드락 (Deadlock)
두 트랜잭션이 서로가 가진 자원을 기다리며 무한 대기하는 상태.
예시
-- Tx1
BEGIN;
LOCK TABLE A; -- A lock
-- 잠시 후
LOCK TABLE B; -- B lock 요청
-- Tx2
BEGIN;
LOCK TABLE B; -- B lock
-- 잠시 후
LOCK TABLE A; -- A lock 요청
🌀 Tx1은 B를, Tx2는 A를 기다리며 서로를 기다리는 교착 상태
📌 5. 데드락 해결 전략
방법 | 설명 |
타임아웃 | 일정 시간 초과하면 강제 rollback |
Wait-for 그래프 | 대기 그래프 생성 → 사이클 감지 시 한 트랜잭션 종료 |
Lock 순서 고정 | 항상 A → B → C 순으로 Lock 획득 (순서 고정) |
📌 6. 2PL의 종류 및 특성 비교
종류 | 설명 |
Conservative 2PL | 트랜잭션 시작 전에 필요한 모든 Lock 미리 획득. 데드락 없음. 비효율적. |
Strict 2PL | write-lock은 commit/rollback 시점에 반환. Recoverable 보장. |
Strong Strict 2PL | read/write-lock 모두 commit/rollback 시점에 반환. 구현 쉬우나, Lock 오래 잡음. |
📌 7. MVCC 소개 (간략) *다음 파트에서 자세히 설명.
Lock 기반 방식은 성능 병목의 원인이 됩니다. 이를 해결하는 방식이 바로 **MVCC (Multi Version Concurrency Control)**입니다.
- 데이터를 수정할 때마다 버전을 새로 생성
- 읽기 트랜잭션은 자신에게 일관된 Snapshot을 보고
- 쓰기 트랜잭션은 충돌 여부만 체크
- 대표 DBMS: PostgreSQL, Oracle, MySQL(InnoDB)
→ read/write 간 충돌을 줄여 성능과 동시성 모두 확보
🧠 마무리 요약
항목 | 설명 |
read-lock | 다중 읽기 허용, 쓰기 차단 |
write-lock | 읽기/쓰기 모두 차단 |
2PL | Lock은 먼저 다 얻고, 해제는 나중에 |
데드락 | 서로가 필요한 Lock을 잡고 무한 대기 |
MVCC | 버전 관리로 read/write 충돌 해결 |