Files
document-haness/docs/clean-architecture-backend-template/tech-log-studio/transaction-deadline-and-pool/concept/concept-deadline-propagation.md
T
DongHyeonkaandClaude Fable 5.1 b25357c48a docs(clean-architecture-backend-template): fold analysis into final and re-select one topic
- analysis/·source-index·state.json 을 final/document.md 제2부·제3부로 접었다. SSOT 는 하나다
- 파일럿 — commit-ambiguity-as-a-result 를 새 기준으로 재선별. 후보 14 → 글감 5
  (PROMOTE 5 · MERGE_INTO 3 · KEEP_IN_SSOT 4 · 보류 2). 기록 5건을 다시 썼고 그림 1개를
  techviz 로 만들었다
- 재선별이 잡은 것: 제1부 §6.2·§11.1 이 자기 §13.2 와 어긋나 있었다(레인을 안 돌렸다 vs
  돌렸다) — 정정. 이미 답이 나와 있던 Question 을 HEAD 재실행 질문으로 다시 세웠다.
  Concept 이 인용한 코드가 SSOT 에 없어 뺐다
- candidateScope·sourceRepository 기록. 나머지 43개 주제는 재선별 대기(PENDING 905)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 12:39:20 +09:00

5.1 KiB

kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, evidenceCapturedOn, assets, evidence, source
kind slug title topic project status sourceRevision rootTreeNode evidenceCapturedOn assets evidence source
CONCEPT deadline-propagation 호출 예산에서 DB 로컬 타임아웃까지의 데드라인 전파 transaction-deadline-and-pool clean-architecture-backend-template 게시 전 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 concept:deadline-propagation 2026-09-01
key file
deadline-propagation ../../../final/evidence/rendered/deadline-propagation.svg
key file
deadline-propagation-diagram ../../../final/assets/diagrams/deadline-propagation.svg
../../../final/evidence/raw/deadline-propagation.txt
원본 분석 절은 final/document.md#3-2 · final/document.md#a05 §3.3 이다.

호출 예산에서 DB 로컬 타임아웃까지의 데드라인 전파

호출자가 가진 시간 예산이 트랜잭션 타임아웃으로, 다시 데이터베이스의 로컬 타임아웃으로 좁혀진다. 각 단계가 앞 단계보다 작아야 상위 호출자가 포기한 뒤에도 하위가 계속 도는 상황이 생기지 않는다.

관계

  • 데드라인은 호출 예산에서 시작해 세 단계로 좁힌다 이 개념을 규칙으로 옮긴 것이다.
  • 쓰기 트랜잭션에는 유한 타임아웃이 필수다 이 전파의 마지막 단계가 없을 때의 문제를 다룬 규칙이다.
  • 세션 스코프 설정은 풀로 돌아간 커넥션에 남는다 로컬 타임아웃을 설정할 때의 함정이다.

본문

호출자의 남은 예산이 세 단계로 좁혀져 DB 세션 설정에 도달하는 구조의 설명이다.

마감이 좁혀지는 세 단계

:::evidence key="deadline-propagation-diagram" alt="호출 예산과 트랜잭션 마감과 DB 로컬 타임아웃이 위에서 아래로 쌓여 있고 오른쪽에 좁아지는 방향 화살표가 있다" caption="마감이 좁혀지는 세 단계" zoom="false" :::

획득 전에 요구하는 것

connectionTimeout + beginBudget + minimumActionWindow + completionMargin을 요구하고, Spring의 초 단위 타임아웃이 1초 미만이면 시작하지 않는다. begin 이후에는 statement/lock/idle 셋을 각각 유도하고 하나라도 1ms 미만이면 거부한다.

예산이 좁혀지는 경로

:::evidence key="deadline-propagation" alt="분석 문서 final/document.md 에서 이 기록의 근거 절을 그대로 잘라낸 18줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="final/document.md 발췌 — 18줄" zoom="true" :::

SET 이 아니라 set_config 인 이유

둘이다 — SET은 파라미터 바인딩 전에 파싱되어 syntax error가 나고, 함수 호출은 값이 statement text에서 빠진다. 세 번째 인자 true가 transaction-local을 뜻한다.

H2가 두 가지에서 다르다

세션 스코프이고 idle 가드가 없다. 그것이 H2의 성질이지 선택이 아니라는 점도 함께 적혀 있다.

:::note

실제 세션에서 SHOW statement_timeout으로 적용을 확인하지 않았다

:::

왜 전파해야 하는가

상위 호출자가 30 초 예산을 갖고 있는데 데이터베이스 쿼리에 타임아웃이 없으면, 호출자가 포기한 뒤에도 쿼리는 계속 돈다. 그 커넥션은 반납되지 않고 풀에서 빠져 있다.

부하가 걸리면 그 상태가 누적된다. 아무도 기다리지 않는 작업이 풀을 점유한다.

계산이 자기 타입을 갖는다

데드라인 계산기가 별도 타입이다. 획득 봉투를 포함하는 형태와 포함하지 않는 형태를 나눠 갖는다.

획득 봉투는 커넥션을 얻는 데 드는 시간이다. 그것을 예산에서 빼지 않으면, 커넥션을 기다리다가 남은 시간이 없는 채로 쿼리를 시작하게 된다.

데이터베이스마다 다른 설정기

로컬 타임아웃을 실제로 거는 방법은 데이터베이스마다 다르다. PostgreSQL 용 설정기와 H2 용 설정기가 따로 있다.

이 분리가 필요한 이유는 두 가지다. 설정 문법이 다르고, 세션 스코프 설정이 커넥션에 남는 방식도 다르다.

세 단계

호출 예산        상위 호출자가 기다릴 수 있는 시간
  ↓ 획득 봉투를 뺀다
트랜잭션 타임아웃  스프링 트랜잭션 템플릿에 설정
  ↓ 여유를 남긴다
DB 로컬 타임아웃   데이터베이스가 스스로 끊는 시간

각 단계가 앞 단계보다 작다. 마지막이 가장 작아야 데이터베이스가 먼저 끊고, 그래야 애플리케이션이 그 실패를 분류할 기회를 갖는다.

:::note

순서가 반대가 되면 애플리케이션이 먼저 타임아웃되고 데이터베이스는 계속 돈다. 그 쿼리는 아무도 결과를 받지 않은 채 자원을 쓴다.

:::

템플릿을 미리 만드는 것과의 관계

트랜잭션 템플릿은 모드마다 미리 만들어져 있고 전부 같은 격리 수준에 고정되어 있다. 템플릿을 호출마다 고쳐 쓰면 경합이 생기기 때문이다.

그래서 데드라인은 템플릿의 필드가 아니라 실행 시점에 계산되어 전달된다.