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

데이터베이스 작업의 멱등성

~12 min · transactions, idempotency

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

응답을 못 받았다고 실패한 건 아니야

네트워크 호출은 데이터베이스가 보기 전에 끊길 수도 있고, 처리는 끝났지만 응답만 사라질 수도 있어. 호출자는 둘을 구분할 수 없으므로 같은 요청을 다시 보내도 안전해야 해.

반복해도 결과가 같은 연산

SET status = 'paid'는 여러 번 실행해도 같은 상태지만 SET balance = balance - 100은 실행할 때마다 달라져. 후자는 멱등하지 않아.

쓰기를 멱등하게 만드는 방법

  • INSERT에는 ON CONFLICT DO NOTHING이나 DO UPDATE를 이용해.
  • 클라이언트가 보낸 멱등성 키를 고유 제약으로 지켜.
  • 가능하면 SET balance = ?처럼 절대값을 쓰고 SET balance = balance - ? 같은 증감은 고유한 작업 기록과 묶어.
  • 같은 요청을 100번 받아도 한 번의 결과만 남는지 시험해.

Code

클라이언트가 제공하는 멱등성 키·sql
CREATE TABLE payments (
    id              UUID PRIMARY KEY,
    idempotency_key TEXT UNIQUE NOT NULL,
    amount          NUMERIC(10,2) NOT NULL,
    status          TEXT NOT NULL DEFAULT 'pending',
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- 같은 키 두 번 → 두 번째 insert 조용히 스킵, 더블-차지 없음
INSERT INTO payments (id, idempotency_key, amount)
VALUES (gen_random_uuid(), :key, :amount)
ON CONFLICT (idempotency_key) DO NOTHING
RETURNING *;
WHERE 조건으로 UPDATE를 멱등하게 만들기·sql
-- 이미 paid 아닐 때만 paid 표시; retry 안전
UPDATE invoices
SET status = 'paid', paid_at = now()
WHERE id = ? AND status <> 'paid';

External links

Exercise

프로젝트에서 증분 UPDATE나 중복 가능한 일반 INSERT처럼 멱등하지 않은 쓰기를 찾아. ON CONFLICT, 멱등성 키, 상태 조건을 붙인 UPDATE 중 하나로 최소 1개를 다시 설계해.

Progress

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

댓글 0

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

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