최근에 직장에서 적용해야하므로 CQRS / ES로 뛰어 들기 시작했습니다. 많은 문제를 해결할 것이기 때문에 우리의 경우에는 매우 유망한 것으로 보입니다.
ES / CQRS 앱이 간단한 은행 사용 사례 (돈을 인출)에 상황에 맞는 것처럼 보이는 방법에 대한 대략적인 이해를 스케치했습니다.
요약하자면, A 개인이 돈을 인출하면 :
- 명령이 내려졌다
- 검증 / 검증을위한 명령이 전달됨
- 유효성 검증에 성공하면 이벤트가 이벤트 저장소로 푸시됩니다.
- 애그리 게이터는 이벤트를 대기열에서 제거하여 집계에 수정 사항을 적용합니다.
내가 이해 한 바에 따르면, 이벤트 로그는 사실의 원천입니다. FACTS의 로그이므로 이벤트 로그를 투영 할 수 있습니다.
자,이 위대한 계획에서 이해하지 못하는 것은이 경우에 일어나는 일입니다.
- 규칙 : 잔액은 음수 일 수 없습니다
- 사람 A의 잔액은 100e입니다
- 개인 A가 100e의 철회 명령을 발행 함
- 유효성 검사가 통과되고 100e 이벤트의 MoneyWithdrewEvent가 생성됩니다.
- 그 동안 개인 A는 100e의 다른 철회 명령을 발행합니다.
- 첫 번째 MoneyWithdrewEvent가 집계되지 않았으므로 집계에 대한 유효성 검사 (아직 업데이트되지 않은)에 대한 유효성 검사가 이루어지기 때문에 유효성 검사가 통과됩니다.
- MoneyWithdrew100e의 이벤트가 다른 시간에 방출됩니다
==> 잔액이 -100e에 일치하지 않는 상태이며 로그에 MoneyWithdrewEvent가 2 개 있습니다.
이 문제를 해결하기위한 몇 가지 전략이 있습니다.
- a) 이벤트 버전에서 이벤트와 함께 집계 버전 ID를 넣어 수정시 버전이 일치하지 않으면 아무 일도 일어나지 않습니다.
- b) 검증 계층이 어떻게 든 하나를 생성해야 함을 암시하는 일부 잠금 전략을 사용하십시오.
전략과 관련된 질문 :
- a)이 경우, 이벤트 로그는 더 이상 진실의 원천이 아니며 처리 방법은 무엇입니까? 또한 인출을 허용하는 것은 완전히 잘못된 반면 클라이언트로 돌아 왔습니다.이 경우 잠금을 사용하는 것이 더 낫습니까?
- b) 잠금 == 교착 상태, 모범 사례에 대한 통찰력이 있습니까?
전반적으로, 동시성을 처리하는 방법에 대한 이해가 정확합니까?
참고 : 나는 같은 짧은 시간에 돈을 두 번 인출하는 것이 불가능하다는 것을 이해하지만 세부 사항을 잃지 않기 위해 간단한 예를 들었습니다.