backend/2026-08-10-idempotency-in-our-decisions2026-08-10
멱등성이 우리 결정에서 요구된 자리들
#실무기록#설계
멱등성이 우리 결정에서 요구된 자리들
resources/concept/ 에 「멱등성」이 없는데, 제품 결정 여덟 건이 그 성질을 각자 다른 말로 요구하고 있었다. 개념 노트를 세우기 위해 그 자리들을 모아 둔 실무 기록이다. 외부 자료 요약이 아니라 이 레포에서 관찰한 것이다.
관찰된 자리
| 결정 | 어떻게 적혀 있나 | 무엇을 두 번 받나 |
|---|---|---|
| CFO-DEC-003 | 「drive_file_id 를 unique key 로 삼아 멱등 upsert 한다」 | Drive 변경 알림 |
| STL-DEC-015 | 「동일 transaction_id 중복 INSERT 차단」 | client verify + webhook 이중 경로 |
| STL-DEC-012 | 「POST /api/subscription/mock-purchase(JWT 필수, 멱등)」 | 결제 트리거 재시도 |
| KDEV-DEC-009 | 「부팅 시 users 에 멱등 upsert」 | 매 부팅 |
| KDEV-DEC-016 | 잔디 착지의 upsert — 같은 날짜를 다시 조사해도 하루 1건 | 재실행 |
| AXKG-DEC-006 | 「email 기준 멱등이며 기존 seed 계정은 흡수된다」 | 로스터 시드 |
| KAG-DEC-007 | 「append 원자성·중복·동시 writer·부분 실패의 판정」 | 재시도된 append |
| KDEV-DEC-013 | 웹소켓 재연결 시 같은 Slack 이벤트가 다시 들어오는 경로 | Socket Mode 재연결 |
공통된 모양
세 가지가 반복된다.
- 재시도가 필연인 자리에서 나온다 — 네트워크·webhook·재연결·재실행. 「두 번 오지 않게」가 불가능해서 「두 번 와도 같게」로 간다.
- 자연키로 막는다 —
drive_file_id·transaction_id·email. 요청마다 새로 만드는 값이 아니라 그 사건을 가리키는 이름을 키로 삼는다. - DB 제약이 최종 방어선이다 — 애플리케이션에서 「있으면 건너뛴다」로 검사해도 동시에 두 개가 들어오면 뚫린다. unique 제약이 마지막에 막는다.
갈리는 지점
- 읽기는 원래 멱등이다. 문제가 되는 것은 쓰기와, 쓰기에 딸린 부작용(발송·결제·알림)이다.
- upsert 가 멱등의 전부는 아니다. 「덮어쓴다」와 「같은 결과를 낸다」는 다르다 — 두 번째 요청이 더 오래된 값을 들고 오면 upsert 는 상태를 되돌린다.
- 부작용이 있는 단계는 재시도가 안전하지 않다. KAG-DEC-007 이 append 원자성을 따로 다루는 이유이고, 결제·발송이 그 부류다.
참고
외부 문헌은 참조하지 않았다. 이 레포의 결정 문서 여덟 건이 원천이다.