fix: 하네스 제거 및 keycloak 문서 보강

This commit is contained in:
DongHyeonka
2026-07-25 12:53:13 +09:00
parent 6c53ded9cb
commit d71669eb59
2329 changed files with 138239 additions and 172816 deletions
@@ -1 +0,0 @@
../../vault/20-evidence/official-docs/skip-locked-postgres-docs.md
@@ -0,0 +1,111 @@
---
title: PostgreSQL FOR UPDATE SKIP LOCKED (공식 문서)
source_type: official-doc
url: https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE
archive_url:
status: raw
confidence: high
tags: [ca-outbox-pattern, postgres, skip-locked, locking, official-doc]
related_projects: [ca-skeleton-operational-contract]
related_branches: [feature-domain-event-outbox-contract, feature-background-job-async-contract]
created: 2026-05-22
last_reviewed: 2026-05-27
---
# PostgreSQL FOR UPDATE SKIP LOCKED (공식 문서)
> Layer: `raw/official-docs/` — PostgreSQL Documentation, SELECT — The Locking Clause 의 **원문 발췌·출처 기록**.
> ca-tmpl 이 채택한 폴링 방식의 **핵심 메커니즘인 `FOR UPDATE SKIP LOCKED`** 자체의 의미와 보장 범위를 공식 문서로 못 박아 두기 위함.
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-domain-event-outbox-contract]] | Topic 3 — Outbox Pattern baseline (SKIP LOCKED polling) 의 DB 측 메커니즘 1차 근거 — Postgres 공식의 inconsistent view / queue-like table 명시 |
| [[raw/branch-notes/feature-background-job-async-contract]] | Background job worker 가 다중 인스턴스로 row 를 안전하게 가져가는 패턴의 DB 근거 |
| [[raw/project-notes/ca-skeleton-operational-contract]] | §18 / §19 의 outbox + polling 채택안 baseline 보조 — SKIP LOCKED 의 동작 보증 |
## 컨텍스트
ca-tmpl 이 채택한 폴링 방식의 **핵심 메커니즘인 `FOR UPDATE SKIP LOCKED`** 자체의 의미와 보장 범위. queue-like table 에서 worker 다중 인스턴스가 서로 다른 row 를 가져가도록 하는 패턴 — outbox table 이 정확히 이 케이스.
## 출처 / Source
- 원본 URL: https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE
- 아카이브 URL: (미수집)
- 저자 / 조직: PostgreSQL Global Development Group
- 발행일: rolling docs (current version)
- 마지막 확인일: 2026-05-27
- **재검증 결과**: 2026-05-27 WebFetch 로 본 페이지의 verbatim 재확인 성공 — `SK-PG-C1`, `SK-PG-C2` 두 인용은 공식 페이지의 정확한 wording 으로 확인됨. `SK-PG-C3` (FOR UPDATE / FOR NO KEY UPDATE 와 SKIP LOCKED 조합) 은 2026-05-22 user 수집 wording 이 2026-05-27 페이지에서 동일 문장으로 발견되지 않음 (페이지 구조상 lock_strength 4종 모두 SKIP LOCKED 와 결합 가능하다고 정리되어 있음, 별도 인용으로 재정리 필요) → `SK-PG-C3``needs-confirmation`.
## 핵심 인용 / Key quotes (verbatim)
> [§The Locking Clause — SKIP LOCKED behavior] "With SKIP LOCKED, any selected rows that cannot be immediately locked are skipped."
> [§The Locking Clause — Inconsistent view warning] "Skipping locked rows provides an inconsistent view of the data, so this is not suitable for general purpose work, but can be used to avoid lock contention with multiple consumers accessing a queue-like table."
> [§The Locking Clause — lock_strength + SKIP LOCKED combinations, user 수집본 2026-05-22 — 재검증 시 동일 문장 미발견] "Both FOR UPDATE and FOR NO KEY UPDATE allow the locking clause to be combined with SKIP LOCKED."
## Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| SK-PG-C1 | SELECT 시 SKIP LOCKED 를 사용하면 즉시 lock 을 잡을 수 없는 row 는 **건너뛴다** (대기하지 않음) | [§The Locking Clause — SKIP LOCKED behavior] "With SKIP LOCKED, any selected rows that cannot be immediately locked are skipped." | `official-vendor-doc` | PostgreSQL SELECT ... FOR ... SKIP LOCKED 의 모든 lock_strength | "건너뛴 row 가 영원히 누락된다"는 뜻은 아님 — 다음 polling 사이클에서 다시 후보가 됨 |
| SK-PG-C2 | SKIP LOCKED 는 데이터의 inconsistent view 를 제공하므로 일반 목적의 read 에는 적합하지 않으며, **queue-like 테이블에 여러 consumer 가 접근할 때 lock contention 을 피하는 용도로 사용** | [§The Locking Clause — Inconsistent view warning] "Skipping locked rows provides an inconsistent view of the data, so this is not suitable for general purpose work, but can be used to avoid lock contention with multiple consumers accessing a queue-like table." | `official-vendor-doc` | queue / outbox / job table 패턴 | "queue-like table 에서는 무조건 SKIP LOCKED 가 best practice" 라는 일반화는 본 인용에 없음 — 단지 contention 회피 도구로 적합 |
| SK-PG-C3 | FOR UPDATE 와 FOR NO KEY UPDATE 둘 다 SKIP LOCKED 와 결합할 수 있다 (2026-05-22 user 수집본 인용 — 2026-05-27 재확인 시 동일 wording 미발견, 현재 페이지는 lock_strength 4종 + SKIP LOCKED 의 조합 가능성을 별도 표현으로 정리) | [§The Locking Clause — lock_strength + SKIP LOCKED combinations] "Both FOR UPDATE and FOR NO KEY UPDATE allow the locking clause to be combined with SKIP LOCKED." | `needs-confirmation` | Postgres 의 lock_strength 와 SKIP LOCKED 조합 | FOR SHARE / FOR KEY SHARE 와의 결합 가능 여부는 본 인용에 포함되지 않음 (현재 페이지 구조상 4종 모두 가능하다고 추정되나 별도 재인용 필요) |
### Strength 정책
- `SK-PG-C1`, `SK-PG-C2`: 2026-05-27 WebFetch 로 verbatim 재확인 성공 → `official-vendor-doc`
- `SK-PG-C3`: user 수집본 wording 이 현재 페이지에서 동일 문장으로 발견 안 됨 → `needs-confirmation`. wiki 승급 전 재인용 필수.
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것**:
- `SK-PG-C1`: SKIP LOCKED 의 정확한 동작 (대기 없이 skip)
- `SK-PG-C2`: queue-like table 의 multiple consumer 시나리오가 Postgres 공식이 인정하는 적용 영역
- **이 자료가 증명하지 않는 것**:
- 순서 보장 — SKIP LOCKED 는 순서를 보장하지 않으며 inconsistent view 라는 명시적 경고가 있음
- MySQL / 다른 RDB 의 동작 — 본 인용은 Postgres 한정
- exactly-once delivery — SKIP LOCKED 는 단순 locking 도구, 처리 중 worker 크래시 시 row 재선택 가능 → at-least-once
- polling interval / batch size 의 최적값
- FOR SHARE / FOR KEY SHARE 의 SKIP LOCKED 결합 가능 여부 (`SK-PG-C3` 한계)
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- ca-tmpl 의 outbox publisher 가 worker 크래시 후 row 재선택 시 중복 발행을 consumer idempotency 로 흡수하는 설계
- 다중 publisher 인스턴스 수 + interval 조합의 실제 throughput (locally-verified 필요)
- 순서가 strict 해야 하는 도메인이라면 partition key + 단일 publisher 또는 CDC 로 전환 필요 (본 자료의 inconsistent view 경고와 결합)
## 메모 / Notes (내 프로젝트 해석 — 직접 인용 아님)
- 적용 시나리오: queue-like table 에서 worker 다중 인스턴스가 서로 다른 row 를 가져가도록 하는 패턴. outbox table 이 정확히 이 케이스.
- 핵심 의미:
- SELECT 시 잠긴 row 를 **기다리지 않고 건너뛴다** (`SK-PG-C1`)
- 결과 집합이 "그 순간 다른 worker 가 안 잡은 row" 라서 정확한 snapshot 이 아님 (문서가 명시: "inconsistent view", `SK-PG-C2`)
- 따라서 일반 read 에는 부적합, **queue 폴링 전용** (`SK-PG-C2`)
- 장점:
- lock contention 제거 → 다중 publisher 인스턴스 수평 확장 가능
- 별도 락 매니저나 분산 락 (Redis 등) 불필요
- 단점:
- 순서 보장 안 됨 (skip 이 되면 다른 worker 가 더 늦은 row 를 먼저 가져갈 수 있음)
- 처리 중 worker 크래시 시 row 가 다시 unlocked → 다른 worker 가 재시도 → at-least-once
- MySQL 은 8.0+ 에서만 지원, MariaDB · 일부 RDB 미지원
- ca-tmpl (SKIP LOCKED polling) 과의 차이: ca-tmpl 이 의존하는 **DB 기능 자체**. 이 문서가 해당 기능의 근거.
- 운영 복잡도: SQL 한 줄. 매우 낮음.
- exactly-once / at-least-once 보장 수준: SKIP LOCKED 자체는 **at-least-once** 패턴의 도구. exactly-once 보장 X.
- 외부 의존성 추가 여부: 없음 (DB 기본 기능).
- 시사점: ca-tmpl 의 "순서가 strict 하지 않아도 됨 + 처리량 우선 + 인프라 단순화" 가정이 깔려 있다는 뜻. 순서가 strict 해야 하면 partition key + 단일 publisher 또는 CDC 가 더 적합.
- 대안 그룹 (Topic 3 — Outbox Pattern): SKIP LOCKED polling 의 메커니즘 — baseline 보조
## Related / 관련
- 같은 주제 다른 official-doc:
- [[raw/official-docs/outbox-skip-locked-microservices-io]] (패턴 정의)
- [[raw/official-docs/outbox-debezium-official-docs]] (대안 1: CDC)
- [[raw/official-docs/dual-write-antipattern-microservices-io]] (negative reference)
- 같은 주제 company-tech-blog:
- [[raw/company-tech-blogs/outbox-woowahan-techblog-pattern]]
- 인용하는 branch / project:
- [[raw/branch-notes/feature-domain-event-outbox-contract]]
- [[raw/branch-notes/feature-background-job-async-contract]]
- [[raw/project-notes/ca-skeleton-operational-contract]]
- 인용한 wiki 요약: (미작성)