본문으로 바로가기

콘텐츠 초기화 동시 실행을 막는 PostgreSQL advisory lock

콘텐츠 DB 초기화는 테이블 생성·스키마 보정·정적 시드·notes/courses 업서를 순서대로 묶습니다. 운영자가 버튼을 두 번 누르거나 console replica가 겹치면, 각 단계가 멱등이어도 두 파이프라인이 중간 상태를 서로 읽을 수 있습니다.

3회 조회약 2분 읽기
X에 공유 새 창에서 열림
목차

콘텐츠 DB 초기화는 테이블 생성·스키마 보정·정적 시드·notes/courses 업서를 순서대로 묶습니다. 운영자가 버튼을 두 번 누르거나 console replica가 겹치면, 각 단계가 멱등이어도 두 파이프라인이 중간 상태를 서로 읽을 수 있습니다.

서버 동시성 계약

POST /api/db/init는 시작 전에 pg_try_advisory_lock을 획득합니다. 이미 다른 세션이 작업 중이면 DB를 더 건드리지 않고 409 INIT_IN_PROGRESS를 반환합니다. lock을 잡은 세션은 전체 callback 동안 유지하고, 성공·실패·예외 뒤 pg_advisory_unlock과 client release를 실행합니다.

운영자에게 보이는 상태

  • 첫 요청만 lock을 획득하는지 확인한다.
  • 겹친 요청이 409로 끝나고 시드 행을 쓰지 않는지 확인한다.
  • 성공과 예외 양쪽에서 lock이 해제되는지 확인한다.

UI 버튼 비활성화는 사용성 보조일 뿐 보안·동시성 계약이 아닙니다. 서버가 반환하는 상태를 role=status 영역에 보여 주고, 운영자는 409를 실패 데이터가 아니라 “현재 작업이 끝난 뒤 재시도할 상태”로 안내해야 합니다.

요청 경합 판정표

상황 서버 행동 UI 안내 재시도
lock 획득 초기화 시작, 단계별 결과 기록 진행 중 완료 전 금지
lock 사용 중 쓰기 없이 409 INIT_IN_PROGRESS 다른 작업이 진행 중 잠시 후 가능
단계 실패 rollback, 오류 단계 반환 변경하지 못함 원인 제거 후
unlock 실패 운영 경고 재실행 전 상태 확인 소유 확인 후
SELECT pg_try_advisory_lock($1);  -- false면 즉시 409
-- 같은 세션에서 전체 초기화 실행
SELECT pg_advisory_unlock($1);    -- finally에서 실행

세션 단위 lock을 잡은 client는 해제 전 pool로 반환하면 안 됩니다. 다른 요청이 같은 세션의 lock 상태를 이어받지 않도록 획득부터 해제까지 같은 client를 보유합니다.

관련 강좌: Expand/Contract와 멱등 백필

quality 카테고리의 다른 글

카테고리 전체 보기 →

이 글이 도움이 되었나요?