그래서, 내가 무엇을 놓치고 있습니까?
추측하기.
가장 먼저 누락 된 것은 재 구축중인 상태에 대한 이벤트 만 다시로드하면된다는 것입니다. 트랜잭션 경계를 깔끔하게 모델링 할 수 있으면 각 객체는 고유 한 ID로 태그가 지정된 이벤트를 작성한 다음 해당 이벤트 만 다시 읽을 수 있습니다. 이벤트 스토리지에 관계형 데이터베이스를 사용하면 해당 쿼리 속도를 높이기 위해 색인화 된 id 열이 있습니다. EventStore를 사용하면 각 객체에는 자체 스트림이 있습니다.
각 트랜잭션에서 단일 객체 만 수정하고 있는지 확인하려면 모델에서주의를 기울여야하므로 시도하려는 각 불변량을 올바르게 분리해야합니다. 억지로 시키다.
충분히 빠르지 않은 경우에도 상태의 스냅 샷을 생성 (memoization)하고 "전통 스토리지"에서이를 유지할 수 있습니다. 각 스냅 샷은 스냅 샷을 빌드하는 데 사용 된 마지막 이벤트의 시퀀스 번호로 태그가 지정됩니다. 다시로드 할 때 리포지토리는 해당 스냅 샷을 먼저 잡고 새로운 이벤트를 적용합니다. (이는 최신 스냅 샷을 가져 오는 합리적인 방법을 의미합니다. 이벤트에도 시퀀스 번호가 지정되어 있거나 시작 지점에 도달 할 때까지 이벤트 스트림을 뒤로 읽을 수있는 효율적인 방법이 있습니다.)
스냅 샷을 병합하지 않고 쓰기와 병렬로 빌드 할 수 있다는 점에서 일반적인 접근 방식에 비해 여전히 이점이 있습니다. 이벤트 리스너를 다른 스레드 / 프로세스에 배치하고 글쓰기와 함께 즐겁게 작성하십시오. 합리적인 일정에 따라 스냅 샷 저장소로 결국, 스냅 샷은 특히시기 적절할 필요는 없습니다. 새로운 이벤트를 다시 적용하는 작업으로 인해 SLA가 손상되지 않는 경우가 많습니다.
(스냅 샷은 마이그레이션을 복잡하게 만듭니다. 모델의 직렬화를 변경하면 스냅 샷 캐시가 무효화됩니다. 물론 마이그레이션의 일부로 새 직렬화를 사용하여 스냅 샷을 다시 빌드 한 다음 변경 사항이 적용되면 "캐치"할 수 있습니다.
이벤트 스트림에서 상태를 복원하는 것이 일반적으로 수행됩니까?
그렇습니다. CQRS 예제에 일반적으로 표시되는 것은 제출 된 명령이 올바르게 구성되었는지 확인한 후 애플리케이션 계층이 저장소에서 도메인 오브젝트를로드하며, 여기서로드는 기본 생성자이며 이벤트 스트림 재생 (또는 이벤트 목록이있는 팩토리 호출).
다른 두 가지 상충적인 생각.
- 저장소 인터페이스 뒤에 캐시가있을 수 있습니다.
- 캐시 무효화는 두 가지 어려운 문제 중 하나입니다.