4

필자가 보았던 여러 가지 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 예제가 훌륭합니다.

답변

1

다른 컴퓨터에서 실행되는 두 개의 개별 클라이언트가 API를 통해 응용 프로그램과 상호 작용할 수없는 이유가 있습니까? 그렇게하면 이벤트의 중앙 처리가 1 대의 시스템에서 처리되고 사용자가 설명하는 문제를 피할 수 있습니다. 부분적으로 연결된 시나리오를 언급한다면 여전히 클라이언트에서이 논리를 수행하지 않을 것입니다. 피할 수없는 경우 이벤트 스트림을 결합하여 충돌을 처리해야합니다.

유용 할 경우 concurrency issues을 처리 할 수있는 게시물이 있지만 정확한 시나리오는 처리하지 못하지만 동시성 충돌 해결에 대한 아이디어를 줄 수 있습니다.

0

기본 데이터베이스가 이미이를 지원할 때 낙관적 동시성 제어를 직접 구현하지 마십시오.

일반적으로 이는 데이터가 예상되는 버전을 데이터베이스 서버에 전달하여 구현됩니다. 버전이 현재 버전과 일치 할 때만 업데이트가 성공적으로 통과합니다.

:

RavenDB는 낙관적 동시성 제어를위한 전자 태그를 사용