필자가 보았던 여러 가지 Greg Young의 영감을받은 사례에 맞게 사례 및 원칙을 사용하여 이벤트 소싱 시스템을 구현하려고합니다.여러 클라이언트에서 낙관적 동시성 검사를 사용하여 이벤트 저장소 구현
버전 확인 논리가 작동하는 방식과 현재 버전이 예상 버전과 일치하지 않으면 집계를 저장할 때 다른 세션/클라이언트 앱이 이전에 집계를 업데이트했다는 것을 이해합니다.
또한 동시 이벤트를 저장할 때 소급 충돌을 해결하는 방법을 사용할 수 있음을 이해합니다.이 질문은 그렇게하는 것이 아닙니다.
내가 이해하려고하는 것은 ravendb와 같은 nosql 데이터베이스를 이벤트 저장소로 사용하는 특정 구현에서 경쟁 이벤트로 인해 작성된 이벤트가 버전 번호와 겹치지 않도록하는 방법입니다.
예제 프로젝트에서 다음 코드는 설명하기 위해 다음 Repository<TAggregate>
저장소 클래스에서
A는 이제 방법을
public void Save(AggregateRoot aggregate, int expectedVersion)
{
if (aggregate.GetUncommittedChanges().Any())
{
lock (_lockStorage)
{
var item = new T();
if (expectedVersion != -1)
{
//issue if two processes get to this line of code below together
//and both have the same 'version to be expected' then start writing together
item = GetById(aggregate.Id);
if (item.Version != expectedVersion)
{
throw new ConcurrencyException(string.Format("Aggregate {0} has been previously modified",
item.Id));
}
}
_storage.Save(aggregate);
}
}
}
을 절약 할 단 하나의 응용 프로그램이있을 때 기본적으로이 잘 작동이 있습니다. 잠금은 현재 스레드가 잠금을 수행하고 버전을 확인한 후 자체 이벤트를 작성한 동안 다른 스레드가 이벤트 저장소에 이벤트를 기록하는 것을 중지합니다.
그러나 서로 다른 컴퓨터에서 실행되는 두 개의 개별 클라이언트를 상상해보십시오. 분명히 두 프로세스가 함께 잠금에 들어갈 수 있고 둘 다 GetById()
메서드를 실행할 수 있으며 둘 다 현재 커밋 된 동일한 버전을 볼 수 있습니다. 두 프로세스는 계속해서 버전 번호가 증가하는 커밋되지 않은 이벤트를 작성합니다. 그러나 이로 인해 동일한 버전 번호의 다른 이벤트가있을 수있는 상태의 집계에 대한 이벤트 스트림이 남습니다.
나는 어떤 종류의 회고 결의안을 할 수는 있지만 그것이 성취하려는 것이 아니라는 것을 알고있다.
이제 이벤트 저장소 데이터베이스 측면에서 일종의 잠금을 수행해야합니다. 아무도 이것을하는 방법을 조언 할 수 있 었는가? 답변은 데이터베이스와 관련이있을 필요는 없지만, 이벤트 소싱 시스템의 프로토 타입을 계획하고 있으므로 ravendb 예제가 훌륭합니다.