Files
llm-wiki/raw/company-tech-blogs/cache-woowahan-after-commit-invalidation.md
T

11 KiB

title, source_type, url, archive_url, status, confidence, tags, related_projects, related_branches, created, last_reviewed
title source_type url archive_url status confidence tags related_projects related_branches created last_reviewed
우아한형제들 — 트랜잭션 커밋 이후 캐시 무효화 (after-commit invalidation 사례) company-tech-blog https://techblog.woowahan.com/2667/ raw medium
ca-cache-consistency
woowahan
after-commit
transaction-synchronization
korean-fintech
ca-skeleton-operational-contract
feature-cache-consistency-contract
feature-transaction-concurrency-contract
2026-05-22 2026-05-27

우아한형제들 — 트랜잭션 커밋 이후 캐시 무효화 사례

Layer: raw/company-tech-blogs/ — 우아한형제들 기술블로그 사례 발췌 (요지 발췌, 한국어). ca-tmpl 의 "cache invalidation = after-commit only" 결정의 사례 근거 (공식 best-practice 가 아닌 case-study 취급).

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-cache-consistency-contract "tx 내부 cache mutation forbidden + afterCommit invalidation 강제" 결정의 한국 도메인 사례 근거. invalidation 실패 → 별도 처리 (observable failure, 재시도/비동기 큐) 요구의 사례 출처
raw/branch-notes/feature-transaction-concurrency-contract TransactionSynchronizationManager.registerSynchronizationafterCommit 후크 활용 패턴의 사례 — port adapter 가 트랜잭션 lifecycle 에 hook 하는 구현 옵션

컨텍스트

ca-tmpl 결정 "cache invalidation = after-commit only" 의 사례 근거. Spring TransactionSynchronizationManager.registerSynchronization 을 실제 도메인에서 쓰는 한국 기업 사례.

출처 / Source

  • 원본 URL: https://techblog.woowahan.com/2667/
  • 보조: 우아한형제들 기술블로그의 다른 캐시 글 묶음 (Redis, 동시성)
  • 참고 검색어: "우아한형제들 캐시 무효화 트랜잭션", "woowahan transactionsynchronization registerSynchronization"
  • 아카이브 URL: (미수집)
  • 저자 / 조직: 우아한형제들 (Woowahan Brothers / Woowa Bros.) — 기술블로그
  • 발행일: rolling docs (페이지 자체에 명시 없음)
  • 마지막 확인일: 2026-05-27
  • 재검증 한계: WebFetch 차단 — 본 인용은 user 수집본 (2026-05-22) 보존, verbatim 재확인 보류. 본 자료의 인용은 "요지 발췌" 로 명시되어 있어 원문 일치도 검증 시 paraphrase 가능성 있음. ca-tmpl 의 verified 승급 전 원문 재확인 의무.

핵심 인용 / Key quotes (verbatim)

[§요지 — 글 본문 요약] needs-confirmation (요지 발췌, paraphrase 가능성): "캐시 무효화를 트랜잭션 내부에서 호출하면, 커밋이 롤백된 경우에도 캐시는 이미 invalidate 된다. 다른 트랜잭션이 그 사이 cache miss → DB 조회로 stale 값을 다시 채우는 race 가 발생했다."

[§해결책] needs-confirmation (요지 발췌): "해결책으로 TransactionSynchronizationManager.registerSynchronization 을 이용해 afterCommit 시점에만 캐시 무효화를 수행하도록 변경했다. 롤백 시에는 캐시를 건드리지 않는다."

[§한계] needs-confirmation (요지 발췌): "단, afterCommit 자체는 트랜잭션 외부이므로 무효화 실패는 별도 처리 (observable failure, 재시도 또는 비동기 큐 전송) 가 필요하다."

[§선언적 대안] needs-confirmation (요지 발췌): "Spring @TransactionalEventListener(phase = AFTER_COMMIT) 로 같은 효과를 더 선언적으로 얻을 수 있다."

Claims Extracted / 추출된 주장

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
WOOWA-CACHE-C1 사례: 트랜잭션 내부 cache invalidation 호출 시 rollback 발생하면 cache 만 invalidate 되고 DB 는 유지 → 동시 다른 tx 의 cache miss → DB 조회 → stale 값 재로딩 race 가 발생 [§요지] needs-confirmation: "캐시 무효화를 트랜잭션 내부에서 호출하면, 커밋이 롤백된 경우에도 캐시는 이미 invalidate 된다. 다른 트랜잭션이 그 사이 cache miss → DB 조회로 stale 값을 다시 채우는 race 가 발생했다." company-case-study 우아한형제들 도메인의 특정 워크로드 (정확한 endpoint 범위는 글에 비명시) 이 race 가 모든 cache + tx 환경에서 항상 발생한다는 일반 best-practice 보장은 아님 — 사례 1건
WOOWA-CACHE-C2 사례 해결책: TransactionSynchronizationManager.registerSynchronizationafterCommit 후크로 cache invalidation 을 commit 이후로 지연 — rollback 시에는 cache 미터치 [§해결책] needs-confirmation: "해결책으로 TransactionSynchronizationManager.registerSynchronization 을 이용해 afterCommit 시점에만 캐시 무효화를 수행하도록 변경했다. 롤백 시에는 캐시를 건드리지 않는다." company-case-study Spring TransactionSynchronizationManager 사용 환경 afterCommit 후크 사용이 모든 도메인에서 표준 패턴이라는 보장은 아님. 단, Spring 공식 javadoc 에 메커니즘은 명시 (별도 raw 필요)
WOOWA-CACHE-C3 사례 한계 인식: afterCommit 은 트랜잭션 외부이므로 cache invalidation 실패 시 트랜잭션이 rollback 되지 않음 → observable failure 노출 + 재시도 / 비동기 큐 전송 등 보상 로직 별도 필요 [§한계] needs-confirmation: "단, afterCommit 자체는 트랜잭션 외부이므로 무효화 실패는 별도 처리 (observable failure, 재시도 또는 비동기 큐 전송) 가 필요하다." company-case-study afterCommit hook 으로 cache invalidation 위임한 모든 환경 본 사례가 제시한 specific 보상 메커니즘 (재시도 vs 비동기 큐) 의 선택 기준은 글에 명시 없음
WOOWA-CACHE-C4 선언적 대안 언급: 동일 효과를 Spring @TransactionalEventListener(phase = AFTER_COMMIT) 로 얻을 수 있다는 언급 [§선언적 대안] needs-confirmation: "Spring @TransactionalEventListener(phase = AFTER_COMMIT) 로 같은 효과를 더 선언적으로 얻을 수 있다." company-case-study Spring 4.2+ 환경 @TransactionalEventListenerregisterSynchronization 보다 모든 면에서 우월하다는 평가는 글에 명시 없음 — listener 미등록 환경 silent drop 위험은 별도 (Spring official 문서 필요)

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것 (재검증 한계 + 사례 한정):
    • WOOWA-CACHE-C1 ~ C4: 우아한형제들이 겪은 특정 race condition + TransactionSynchronizationManager.afterCommit 채택 + 외부 처리 필요성 인식 + @TransactionalEventListener 대안 언급
  • 이 자료가 증명하지 않는 것 (company-tech-blog 일반 한계 + 본 사례 한정):
    • 한국 기업 표준 / Spring 공식 권장 — 본 자료는 사례 1건 (CLAUDE.md §5: "공식 best-practice 로 취급 금지")
    • 모든 cache + tx 조합에서 afterCommit 패턴이 최적이라는 일반화 — 사례의 워크로드 특성 (read-heavy / write 빈도) 미명시
    • TransactionSynchronizationManager vs @TransactionalEventListener 의 선택 기준 — 글이 두 옵션을 언급하나 비교 분석 부재
    • cache invalidation 실패의 정확한 모니터링 / alert 메커니즘 — "observable failure" 만 언급, 구현 디테일 부재
    • 본 자료 단독으로 afterCommit 패턴을 "official best practice" 로 격상 불가 → Spring 공식 문서 (별도 raw) 와 corroborate 필요 (다른 raw 의 official-vendor-doc strength claim 과 결합 시에만 일반화 가능)
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
    • 재검증 한계로 인한 SSOT 확인 의무: ca-tmpl 의 verified / published-ready 승급 전, 원문 직접 재확인하여 paraphrase vs verbatim 명확화
    • ca-tmpl 의 CACHE/INVALIDATION_FAILURE error code 분류가 본 사례의 "observable failure" 시맨틱과 일치하는지 (재시도 정책, alert 임계값 등)
    • @TransactionalEventListener 채택 시 listener bean 등록 누락에 대한 build-time/test-time 검출 가드 (silent drop 방지)

메모 / Notes (내 프로젝트 해석)

본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.

  • ca-tmpl 결정과의 정합성:
    • "tx 내부 또는 tx 미참여 상태에서의 cache mutation 은 forbidden" ← 같은 문제의식 (WOOWA-CACHE-C1).
    • "invalidation 실패가 조용히 무시되면 실패" 테스트 ← 우아한형제들 사례의 후속 문제 (afterCommit 외부 실패 처리, WOOWA-CACHE-C3).
  • 두 가지 구현 옵션 (둘 다 본 사례에서 언급):
    1. TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { afterCommit() { … } }) — adapter 에서 직접 등록.
    2. domain event 발행 + @TransactionalEventListener(phase = AFTER_COMMIT) — 더 선언적, 그러나 listener 가 등록 안 된 환경에서 silent drop 위험.
  • ca-tmpl test 계약 매핑:
    • "tx rollback 시 cache 에 stale write 가 남으면 실패" ← afterCommit 강제로 자동 만족.
    • "invalidation 실패가 조용히 무시되면 실패" ← afterCommit 안에서 발생한 RedisConnectionException 을 swallow 하면 실패. ca-tmpl 은 별도 error code (CACHE/INVALIDATION_FAILURE) 로 분류 권장.
  • 취급 주의: 회사 기술블로그는 "공식 best-practice 가 아님" (CLAUDE.md §5). 패턴 자체는 Spring 공식 문서가 권장 (@TransactionalEventListener Javadoc — 별도 official-vendor-doc 인용 필요).
  • 시사점: ca-tmpl 의 결정은 우아한형제들 사례 + Spring 공식 메커니즘의 교집합. 임의 결정 아님 — 단, 본 raw 단독으로는 사례 근거이며 official-vendor-doc raw 와 corroborate 시에만 일반화 가능.