Files
document-haness/docs/clean-architecture-backend-template/tech-log-studio/commit-ambiguity-as-a-result/decision/decision-completion-unknown-is-never-retried.md
T
DongHyeonkaandClaude Opus 5 b2963105a8 docs(keycloak-session-store): import the session-storage lab as a new project
The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.

Follows the import procedure in README.md.

  source/     the originating repository verbatim — 78 documents, 28 SVGs,
              8 manifests, plus .source-revision recording the commit
  final/      the SSOT
    document.md   729 lines written from the 29 experiment documents, not
                  concatenated: what was predicted, what was measured, and
                  where the measurement itself was wrong
    evidence/raw    125 outputs, flattened to <experiment>__<file> because
                    the originals collided (01-baseline.txt appeared three
                    times) and the audit only globs the top level
    evidence/meta   one per raw file; command and exitCode are null and the
                    README says why rather than inventing them
    evidence/browser  22 captures
    assets/       three diagrams through techviz
    .techviz/     their VizSpecs

A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.

Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.

verify-pipeline.py passes. audit-records.py reports no issues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:51:59 +09:00

3.3 KiB

kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, decisionStatus, decidedOn, source
kind slug title topic project status sourceRevision rootTreeNode decisionStatus decidedOn source
PROJECT_DECISION completion-unknown-is-never-retried completion-unknown은 자동으로도 수동으로도 재시도하지 않는다 commit-ambiguity-as-a-result clean-architecture-backend-template 게시 전 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 decision:completion-unknown-is-never-retried ADOPTED 2026-08-11
docs/adr/ADR-JPA-003-completion-unknown.md — Status Accepted, Date 2026-08-11, Design §17
src/adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/transaction/CommitFailureClassifier.java
src/adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/api/transaction/TransactionCompletionEvidence.java
analysis/05-adapter-outbound-persistence-jpa.md

completion-unknown은 자동으로도 수동으로도 재시도하지 않는다

결정문

커밋 결과를 알 수 없는 실패는 자동으로도 수동으로도 재시도하지 않고 조정으로 넘긴다.

판단 이유

ADR 의 근거는 이 실패가 일시적인 것이 아니라 인식론적이라는 관찰이다. 연결이 커밋 도중에 끊기면 서버는 커밋했을 수도 있고 확인 응답만 유실됐을 수도 있으며, 드라이버는 그 둘을 구별하지 못한다.

커밋됐을 수도 있는 쓰기를 재시도하는 것은 이 플랫폼이 할 수 있는 가장 해로운 일이다. 재시도가 성공하면 중복이 생기고, 그 중복은 원래 실패보다 알아채기 어렵다.

그래서 이 예외는 좁은 조건에서만 만들어진다. 관측된 단계가 COMMITTING 이고, 동시에 SQLSTATE 나 예외 타입이 결과를 말해 주지 못하는 경우다.

그리고 이 불변식은 정책이 아니라 타입 수준에서 강제된다. completionUnknown 이면서 retryable 인 실패 컨텍스트는 생성자가 거부하므로 존재할 수 없다. 정책 버그가 그 조합을 만들 수 있는 경로 자체가 없다.

영향

감수하는 것

조정 큐가 생기고 그것을 읽는 운영 절차가 필요하다. 자동으로 해소되지 않는 항목이 쌓인다.

조정 큐가 무의미해지지 않도록 모호성 규칙을 좁게 유지해야 한다. 넓히면 평범한 풀 고갈과 서버 재시작이 큐로 밀려들고, 운영자는 큐를 읽지 않고 비우는 습관을 배운다.

실제로는 롤백된 트랜잭션도 조정으로 넘어간다. 드라이버가 말해 주지 않았으므로 구별할 수 없다.

얻는 것

중복 쓰기가 자동 경로에서 발생하지 않는다.

모르는 것이 상태로 남아서 나중에 사람이 판단할 재료가 보존된다.

근거

  • pg_terminate_backend가 57P01로 도착하고 커밋 레코드는 이미 WAL에 있었다 이 결정이 다루는 실패가 실제로 어떤 모습인지 보여 주는 사례다.
  • 모르는 것은 성공도 실패도 아닌 세 번째 결과여야 한다 이 결정이 전제하는 상태 어휘다.
  • 위험한 조합은 정책이 아니라 생성자가 거부하게 만든다 이 결정을 타입 수준에서 강제하는 방법이다.
  • 커밋 모호성 판정은 넓혀도 좁혀도 해롭다 이 결정의 조건을 어디에 둘지 정하는 기준이다.