449. 동시성 제어 잠금 (Locking) S-락 / X-락

⚠️ 이 문서는 화장실 문 하나를 두고 수만 명이 동시에 달려들 때, **"구경만 하는 사람(Read)"과 "안에서 청소를 하는 사람(Write)"을 구분하여 가장 효율적으로 화장실 문을 걸어 잠그고 여는 데이터베이스의 원초적인 기술인 'Locking(잠금)'**을 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 여러 트랜잭션이 동시에 같은 데이터를 건드리지 못하게 막는(병행 제어) 가장 기본적인 무기다.
  2. S-락 (Shared Lock): 데이터를 '읽기'만 할 때 거는 자물쇠다. 남들이 같이 읽는 것(S)은 허락하지만, 남이 수정(X)하는 것은 막는다. (공유 자물쇠)
  3. X-락 (Exclusive Lock): 데이터를 '수정'할 때 거는 자물쇠다. 내가 수정하는 동안에는 남들이 읽지도, 수정하지도 못하게 완벽하게 독점(Exclusive)한다. (독점 자물쇠)

Ⅰ. 개요: 화장실 문 닫기 (Context & Necessity)

데이터베이스의 목적은 수만 명의 접속자가 동시에 데이터를 안전하게 읽고 쓰는 것이다.

  • A와 B가 동시에 통장 잔고 100만 원을 읽어갔다.
  • A는 10만 원을 더해서 110만 원으로 저장하려고 한다.
  • B는 5만 원을 더해서 105만 원으로 저장하려고 한다. 이대로 두면 나중에 저장한 사람의 값만 남는 '갱신 손실(Lost Update, 445번 문서)'이 발생한다.

이를 막으려면 "내가 통장을 보고 있으면, 넌 밖에서 기다려!"라고 문을 잠가야 한다. 이 문을 잠그는 기술을 **Locking(락링)**이라고 부른다.

📢 섹션 요약 비유: 로킹은 **'박물관의 미술품 관람 규칙'**과 같습니다. 그림을 그냥 눈으로만 보는(SELECT) 사람들은 여러 명이 동시에(S-락) 그림 앞에 서 있을 수 있습니다. 하지만 그림을 복원하러 온 미술가(UPDATE)가 등장하면, 다른 사람들은 아무도 그림을 볼 수 없게 장막(X-락)을 치고 혼자서만 작업해야 합니다.


Ⅱ. 잠금의 2가지 종류 (S-Lock vs X-Lock) ★

어떤 자물쇠를 걸었느냐에 따라 남들이 할 수 있는 행동이 달라진다. 시험의 핵심이다.

1. 공유 잠금 (S-Lock, Shared Lock)

  • 용도: 데이터를 읽을 때 (SELECT) 쓴다.
  • 규칙: 내가 S-락을 걸면, 남들도 S-락을 걸고 들어올 수 있다. (같이 읽기 가능 🟢)
  • 방어: 내가 S-락을 걸고 읽는 중에는, 남이 X-락(수정)을 걸고 들어올 수 없다. (내가 다 읽을 때까지 기다려야 함 🔴)

2. 배타 잠금 (X-Lock, Exclusive Lock)

  • 용도: 데이터를 수정할 때 (INSERT, UPDATE, DELETE) 쓴다.
  • 규칙: 내가 X-락을 걸면, 남들은 S-락(읽기)도 못 걸고 X-락(수정)도 못 건다. (완벽한 독점 🔴)
  • 효과: 완벽하게 데이터를 보호하지만, 너무 오래 쥐고 있으면 밖에서 대기하는 사람들이 많아져서 서버가 멈춘다(Deadlock).

Ⅲ. 락의 호환성 매트릭스 (Compatibility Matrix)

내가 락을 쥐고 있을 때, 남이 똑같은 데이터에 락을 걸려고 하면 어떻게 될까?

나의 상태 \ 남의 요청S-락 (읽기 요청)X-락 (수정 요청)
S-락 쥐고 있음🟢 허용 (같이 읽자)🔴 대기 (나 다 읽을 때까지 기다려)
X-락 쥐고 있음🔴 대기 (나 고치는 중이야 보지 마)🔴 대기 (나 고치는 중이야 건들지 마)

Ⅳ. 2단계 잠금 규약 (2PL - Two-Phase Locking)

"그럼 자물쇠를 언제 걸고 언제 풀어야 하지?" 수학자들이 락 때문에 꼬이는 문제를 막기 위해 만든 절대 규칙이다. "자물쇠를 거는 단계와 푸는 단계를 완벽하게 분리해라!"

  1. 확장 단계 (Growing Phase):
    • 락을 계속 걸기만 할 수 있고, 풀 수는 없는 단계다. (계속 자물쇠를 채움)
  2. 수축 단계 (Shrinking Phase):
    • 락을 하나라도 풀기 시작했으면, 이제부터는 새로운 락을 걸 수 없는 단계다. (자물쇠를 풀기만 함)

이 규칙을 지키면 '직렬성(Serializable, 완벽한 고립성)'이 100% 보장된다. 하지만 자물쇠를 쥐고 있는 시간이 길어지므로 데드락(교착 상태)에 빠질 위험이 커진다.

┌──────────────────────────────────────────────────────────────┐
│           동시성 제어 락(Lock)의 작동 타임라인 시각화                │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ 시간 │ 트랜잭션 A (SELECT)         │ 트랜잭션 B (UPDATE)             │
│ ───┼─────────────────────────┼─────────────────────────────│
│ T1 │ S-Lock 획득! 🔒           │                             │
│ T2 │ 데이터 읽는 중... 📖       │ X-Lock 요청 (대기 시작 ⏳)      │
│ T3 │ 데이터 다 읽음!            │ (계속 대기 중...) ⏳            │
│ T4 │ S-Lock 해제! 🔓           │                             │
│ T5 │                         │ X-Lock 획득 성공! 🔒 (이제 수정) │
│                                                              │
│ ★ 특징: A가 다 읽을 때까지 B는 얌전히 기다려야 하므로 데이터가 꼬이지 않는다.│
└──────────────────────────────────────────────────────────────┘

Ⅴ. 결론

"가장 완벽한 자물쇠는 가장 끔찍한 병목이다." 초창기 데이터베이스는 이 S-락과 X-락만으로 시스템을 굴렸고, 수강 신청 날만 되면 X-락 대기열이 수천 명씩 쌓여서 서버가 뻗었다. 현대의 RDBMS(MySQL InnoDB 등)는 성능을 위해 읽기 작업(SELECT)에 락을 걸지 않고 스냅샷을 보여주는 MVCC(다중 버전 동시성 제어) 기술을 도입하여 락의 의존도를 획기적으로 낮추었다. 하지만 본질적인 데이터 수정 시 발생하는 X-락의 원리를 이해하지 못하면, 비즈니스 로직에서 발생하는 교착 상태(Deadlock)의 원인을 영원히 찾을 수 없을 것이다.


📌 관련 개념 맵

  • 해결하려는 문제: 갱신 손실 (Lost Update - 445번 문서)
  • 발전된 기술: MVCC (Multi-Version Concurrency Control)
  • 위험 부작용: Deadlock (교착 상태 - 서로의 자물쇠가 풀리기만을 무한정 기다리는 락의 감옥)
  • 락의 크기 (Granularity): Row Lock(한 줄만 잠금) $\leftrightarrow$ Table Lock(테이블 전체 잠금)

👶 어린이를 위한 3줄 비유 설명

  1. 화장실에 사람이 있을 때, S-락과 X-락이라는 두 가지 문패가 있어요.
  2. S-락은 '청소 검사 중' 문패예요. 다른 친구가 들어와서 같이 쓱 둘러보는 건 괜찮지만, 변기를 쓰거나 고치는 건 안 돼요.
  3. X-락은 '수리 중' 문패예요. 수리공 아저씨가 혼자 들어가서 문을 쾅 닫고 고치고 있으니까, 다른 사람은 보지도 쓰지도 못하고 밖에서 기다려야 한답니다!