본문 바로가기
C.W.K.
Stream
Lesson 06 of 10 · published

교착 상태는 어떻게 생기나

~12 min · transactions, deadlocks

Level 0스키마 새싹
0 XP0/86 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

두 트랜잭션이 반대 순서로 잠글 때

트랜잭션 A가 행 X를 잡고 Y를 기다리는데 B는 Y를 잡고 X를 기다리면 순환이 생겨. PostgreSQL은 이를 감지해 한쪽을 중단하고 40P01 deadlock_detected 오류를 돌려줘.

행 2개를 다루는 순서를 통일해

코드 경로마다 항상 행 1을 먼저, 행 2를 나중에 잠그면 같은 일을 하는 트랜잭션끼리 교착 상태가 생기지 않아. 실제 교착 상태 대부분은 이 순서 불일치의 변형이야.

40P01은 재시도할 수 있는 오류야

모든 교착을 미리 없앨 수는 없어. 40P01을 만나면 트랜잭션 전체를 버리고 잠깐 기다린 뒤 다시 실행해. 행 1·2를 다루는 두 경로 모두 같은 규칙을 따르는지 감사해야 해.

Code

교착 상태를 만드는 순서·sql
-- Session A                        | -- Session B
BEGIN;                              | BEGIN;
UPDATE accounts SET balance =       | UPDATE accounts SET balance =
  balance - 100 WHERE id = 1;       |   balance - 100 WHERE id = 2;
                                    |
-- A 가 B 의 2 lock 기다림           | -- B 가 A 의 1 lock 기다림
UPDATE accounts SET balance =       | UPDATE accounts SET balance =
  balance + 100 WHERE id = 2;       |   balance + 100 WHERE id = 1;
-- ERROR: deadlock detected         |
예방: 늘 같은 순서로 잠그기·sql
-- 항상 낮은-id 행 먼저 lock
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = LEAST(1, 2);
UPDATE accounts SET balance = balance + 100 WHERE id = GREATEST(1, 2);
COMMIT;
Python의 재시도 반복문·python
import psycopg, time
for attempt in range(5):
    try:
        with conn.transaction():
            conn.execute("UPDATE accounts SET balance = balance - 100 WHERE id = %s", (from_id,))
            conn.execute("UPDATE accounts SET balance = balance + 100 WHERE id = %s", (to_id,))
        break
    except psycopg.errors.DeadlockDetected:
        time.sleep(0.05 * (2 ** attempt))  # 지수 backoff
else:
    raise RuntimeError("deadlock-retry exhausted")

External links

Exercise

psql 세션 2개에서 교착 상태 예제를 재현하고 deadlock_detected 오류를 관찰해. 이어서 두 트랜잭션이 같은 순서로 행을 잠그도록 바꾸고 교착 상태가 다시 생기지 않는지 확인해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.