DDD - 이벤트 소싱 패턴

오픈소스·2023년 7월 8일
0
post-thumbnail

https://product.kyobobook.co.kr/detail/S000061352142, Ch 7

표 7-1, 상태 기반 모델

lead-idnamestatusphone-number-on
1CONVERTED
2CLOSED
6NEW_LEAD
9FOLLOWUP_SET
15PAYMENT_FAILED
18PENDING_PAYMENT

이벤트 소싱 패턴은 데이터 모델에 시간 차원을 도입한다.

애그리리게이트의 현재 상태를 반영하는 스키마 대신 이벤트 소싱 기반 시스템은 애그리게이트의 수명주기의 모든 변경사항을 문서화하는 이벤트를 유지한다.

public class LeadSearchModelProjection
{
	...
    
    public void Apply(LeadInitialized @event)
    {
    	...
        Version = 0;
    }
    
    public void Apply(ContactDetailsChanged @event)
    {
    	...
        Version += 1;
    }

    public void Apply(Contacted @event)
    {
        Version += 1;
    }
    
    public void Apply(FollowupSet @event)
    {
        Version += 1;
    }

    public void Apply(OrderSubmitted @event)
    {
        Version += 1;
    }

    public void Apply(PaymentConfirmed @event)
    {
        Version += 1;
    }
}

애그리게이트의 이벤트를 반복해서 순서대로 적절히 재정의한 Apply 매서드에 넣의면 표 7-1의 테이블에 모델링된 상태 표현이 정확하게 만들어진다.

각 이벤트를 적용한 후 증가하는 버전 필드에 주목하자. 해당 값은 비즈니스 엔티티에 가해진 모든 변경의 회수를 나타낸다. 또한 이벤트의 일부만 적용한다고 가정한다. 이 경우 '시간 여행'을 할 수 있다.

원천 데이터

그림 7-1, 이벤트 소싱 애그리게이트

이벤트 스토어

이벤트 스토어는 추가만 가능한 저장소이므로 이벤트를 수정하거나 삭제할 수 없다.

본질적으로 이벤트 소싱 패턴은 새로운 것이 아니다. 금융 산업에서는 이벤트를 사용하여 원장의 변경사항을 나타낸다. 원장은 트랜잭션을 문서화하는 추가 전용 로그다. 계정 잔액과 같은 현재 상태는 원장의 기록을 프로젝션해서 언제든지 추론할 수 있다.

이벤트 소싱 도메인 모델

이벤트 소싱 애그리게이트에 대한 각 작업은 다음 단게를 따른다.

  • 애그리게이트의 도메인 이벤트를 로드한다.
  • 이벤트를 비즈니스 의사결정을 내리는 데 사용할 수 있는 상태로 프로젝션해서 상태 표현을 재구성한다.
  • 애그리게이트의 명령을 실행하여 비즈니스 로직을 실행하고 결과적으로 새로운 도메인 이벤트를 생성한다.
  • 새 도메인 이벤트를 이벤트 스토어에 커밋한다.

애플리케이션 서비스는 앞에서 설명한 과정을 따른다. 관련 티켓의 이벤트를 로드하고, 애그리게이트 인스턴스를 리하이드레이션하고, 관련 명령을 호출하고, 변경사항을 데이터베이스에 다시 저정한다.

왜 '이벤트 소싱 도메인 모델'일까?
이벤트를 사용하여 상태 전화(이벤트 소싱 패턴)을 나타내는 것은 도메인 모델의 구성요소가 있든 없든 가능하다. 따라서 필자는 도메인 모델 애그리게이트의 수명주기 변경을 나타내기 위해 이벤트 소싱을 사용하고 있음을 명시적으로 보여주는 방법을 선택했다.

장점

  • 시간여행
    소급 디버깅(retroactive debugging)
  • 심오한 통찰력
  • 감사 로그(Audit Log)
  • 고급 낙관적 동시성 제어
    고급 낙관적 동시성 모델은 일기 데이타가 기록되는 동안 다른 프로세서에 의해 덮어 쓰여지는 경우 예외를 발생시킨다.

단점

  • 학습곡선
    패턴이 데이타를 관리하는 기존 기술과 엄청난 차이가 있다는 것은 명백한 단점이다.
  • 모델의 진화
    이벤트 소싱의 정의를 엄밀하게 따지면 이벤트는 변경할 수 없다.
  • 아키텍처 복잡성

당면한 작업에 이 패턴을 적용할 당위성이 없으며, 대신 더 단순한 설계로 해결할 수 있는 경우라면 앞에 제시한 모든 문제는 훨씬 더 심각해진다.


모든 애그리게이트 관련 작업은 단일 애그리게이트 컨텍스트에서 수행되므로 이벤트 스토어는 애그리게이트 ID로 분할할 수 있다. 애그리게이트의 인스턴스에 속하는 모든 이벤트는 단일 샤드(shard)에 있어야 한다.


  • reponse의 응답속도를 고려한 전통적 방식

  • request의 순수성을 형상관리하는 방식

0개의 댓글