Strong vs eventual consistency

judgment
상황

결제가 완료되면 주문 상태, 재고, 포인트, 알림을 전부 바꿔야 합니다. 이걸 다 한 트랜잭션으로 묶을지, 돈과 상태만 묶고 나머지는 이벤트로 몇 초 뒤에 맞출지 정해야 하는 상황입니다.

😴 Boring — 강한 일관성 — 단일 DB, 한 트랜잭션

언제: 돈, 재고, 주문 상태처럼 틀리면 바로 사고가 나는 데이터일 때. 그리고 쓰기 트래픽이 DB 한 대로 충분히 감당될 때. 대부분의 서비스는 여기서 끝납니다.

비용: 쓰기 처리량이 DB 한 대의 한계에 묶입니다. 트랜잭션 안에 일을 많이 넣을수록 락을 오래 잡아서, 트래픽이 늘면 대기 시간이 같이 늘어납니다.

✨ Novel — 최종 일관성 — 이벤트 기반 비동기 전파 (outbox + 큐)

언제: 알림, 집계, 검색 인덱스처럼 몇 초 늦어도 사용자가 못 느끼는 데이터일 때. 또는 여러 서비스가 같은 데이터에 동기로 묶여서 서로 발목을 잡기 시작할 때.

비용: 중복·순서 꼬임·유실을 직접 처리해야 합니다(멱등 키, 재시도, DLQ). 장애 추적이 어려워지고, "잠깐 안 맞는 화면"을 CS팀과 비즈니스가 감수해야 합니다.

⚖️ 기본 판단

기본은 단일 DB에 한 트랜잭션입니다. 돈과 상태 전이는 끝까지 트랜잭션 안에 둡니다. 쓰기 p99가 락 대기 때문에 실제로 무너지거나, 트랜잭션 안에서 다른 서비스를 동기 호출하고 있는 걸 발견하는 순간 — 그때 부가 데이터부터 outbox 이벤트로 빼서 최종 일관성으로 갑니다.

🚨 트립와이어 — 이 신호가 오면 바꾼다
  • 쓰기 p99가 500ms를 넘고, 원인을 따라가 보니 락 대기(lock wait)일 때
  • 트랜잭션 안에서 외부 서비스 API를 동기 호출하고 있을 때 — 남의 장애가 내 DB 락을 잡고 있는 구조
  • 기능 하나 배포하는데 두 팀이 같이 묶여서 매번 릴리즈 조율 회의가 필요할 때
  • 읽기:쓰기가 10:1을 넘는데 읽기 부하 때문에 주 DB CPU가 70%를 넘나들 때

🔧Postgres transactions (single primary)Transactional outboxKafka/SQS + idempotent consumerRead replicaDLQ + replay

🗣 영어 한 줄 평결

I start with one transaction in one database, and only go eventual when lock waits or team coupling actually bite.

checking microphone…

⚔️ Defend it — AI 시니어가 반박한다. 영어로 버텨라.

첫 메시지로 네 입장을 영어로 선언해라 — 예: “I'd start with 강한 일관성 — 단일 DB, 한 트랜잭션 here, and only switch when …” 그러면 상대가 반박을 시작한다. 근거·숫자·트립와이어로 받아쳐라.

두어 번은 치고받은 뒤에 채점