본문 바로가기

이벤트 기반 아키텍처 (1)

@정소민fan2026. 1. 30. 21:35

애플리케이션이 커지고 복잡해질수록 '어디까지를 하나의 작업으로 묶어야 하는가'에 대한 고민이 깊어진다. 오늘은 트랜잭션의 범위를 좁히고, 시스템 간의 결합도를 낮추는 이벤트 기반 아키텍처의 핵심 개념을 정리해본다.

1. 트랜잭션의 범위는 최소한으로

트랜잭션은 데이터의 무결성이 보장되는 선에서 최대한 작게 가져가는 것이 원칙이다. 하나의 트랜잭션이 너무 많은 작업을 물고 있으면 여러 문제가 발생한다.

  • 성능 저하와 데드락: 트랜잭션 내에서 너무 많은 행을 수정하거나 느린 조회를 수행하면, DB Lock이 길게 유지된다. 이는 다른 요청의 대기 시간을 늘리고 결국 데드락(Deadlock) 상황을 초래할 수 있다.
  • 관심사의 혼재: DB 작업과 상관없는 외부 API 호출이나 알림 발송 로직이 트랜잭션 안에 섞여 있으면, 외부 작업의 실패가 비즈니스 핵심 로직의 롤백으로 이어지는 불합리한 상황이 생긴다.

2. 이벤트를 통한 관심사의 분리

이벤트 기반 흐름 제어를 사용하면 핵심 로직부가 로직을 깔끔하게 나눌 수 있다.

  • 사례: 쇼핑몰 주문 시스템
    • 핵심 로직: 포인트 차감, 결제 정보 저장, 주문 상태 변경
    • 부가 로직: 외부 분석 플랫폼에 데이터 전달, 구매 환영 메일 발송
  • 이 두 로직을 같은 트랜잭션에 묶으면, 분석 플랫폼 서버가 잠깐 죽었을 뿐인데 사용자의 주문 자체가 실패하게 된다.
  • 이때 주문 완료 시점에 '주문됨' 이벤트를 발행하고, 부가 로직들이 이를 구독해서 각자 처리하게 만들면 주문 로직은 외부 상황에 영향을 받지 않고 성공적으로 마무리된다.

3. 보상 트랜잭션

이벤트를 이용해 도메인을 분리하고 이를 별도 서버로 구축한 것이 바로 MSA다. 하지만 분산 환경에서는 기존의 단일 DB 트랜잭션을 사용할 수 없다.

이때 필요한 것이 보상 트랜잭션이다.

  • 상황: 포인트 차감 → 주문 생성 → 재고 차감 순으로 흐름이 이어질 때, 마지막 '재고 차감'에서 실패가 발생했다고 가정하자.
  • 모놀리식 환경에서는 DB가 알아서 롤백해주지만, 서버가 분리된 환경에서는 이미 성공한 '포인트 차감'과 '주문 생성'을 수동으로 되돌려야 한다.
  • 즉, 재고 차감 실패 이벤트를 발행하고, 이를 받은 포인트 모듈과 주문 모듈이 각자 복구 로직을 실행하는 과정이 필요하다.

4. Saga 패턴

여러 서비스에 걸쳐 있는 비즈니스 로직의 원자성을 보장하기 위해 사용되는 대표적인 패턴이 Saga 패턴이다. 크게 두 가지 방식으로 나뉜다.

① 코레오그래피 (Choreography)

  • 특징: 중앙 제어자 없이 서비스끼리 이벤트를 주고받으며 다음 단계를 진행한다.
  • 장점: 구조가 단순하며 각 서비스 간의 결합도가 낮다.
  • 단점: 비즈니스 흐름이 복잡해지면 어떤 서비스가 어떤 이벤트를 구독하고 있는지 파악하기 어렵다.

② 오케스트레이션 (Orchestration)

  • 특징: 별도의 '오케스트레이터'가 전체 흐름을 지휘한다. 각 서비스에 "이거 해"라고 명령을 내리고 결과를 보고받는다.
  • 장점: 복잡한 비즈니스 워크플로우를 한곳에서 관리할 수 있어 가시성이 좋다.
  • 단점: 오케스트레이터 자체가 복잡해질 수 있고, 관리를 위한 추가 인프라 비용이 든다.
정소민fan
@정소민fan :: 코딩은 관성이야

코딩은 관성적으로 해야합니다 즐거운 코딩 되세요

목차