2013-07-28 4 views
1

도메인 이벤트로 채워진 비정규화된 읽기 모델로 RavenDB를 사용하고 있습니다. 두 이벤트 (Created 및 Updated)를 동시에 비정규 화하는 문제가 발생했습니다. Created 이벤트로 변경 한 내용을 저장하기 전에 Updated 이벤트로 업데이트 할 문서가로드됩니다. 나는 문서 작성을 기다릴 변경 API를 기반으로 솔루션을 내놓았다했습니다RavenDB - 문서 작성을 기다립니다.

public static T WaitAndLoad<T>(this IDocumentSession @this, ValueType id) 
     where T : class 
    { 
     var fullId = @this.Advanced.DocumentStore.Conventions.FindFullDocumentKeyFromNonStringIdentifier(id, typeof(T), false); 

     var ev = new ManualResetEvent(false); 

     var cancelation = new CancellationTokenSource(); 

     @this.Advanced.DocumentStore 
      .Changes() 
      .ForDocument(fullId) 
      .Subscribe(change => 
       { 
        if (change.Type == DocumentChangeTypes.Put) 
        { 
         ev.Set(); 
        } 
       }, cancelation.Token); 


     try 
     { 
      var existing = @this.Load<T>(id); 

      if (existing != null) 
      { 
       return existing; 
      } 

      ev.WaitOne(); 

      return @this.Load<T>(id); 
     } 
     finally 
     { 
      cancelation.Cancel(); 
     }    
    } 

불행하게도 두 번째 문서의 이드 InMemoryDocumentSessionOperations에 knownMissingIds 필드에 이미 서버에는 요청이 없기 때문에 null이 반환을로드하기 위해 호출합니다.

문서가 작성 될 때까지 기다리는 다른 방법이 있습니까?

답변

2

글쎄, 이벤트 처리에 어떤 메커니즘을 사용하고 있는지 잘 모르겠지만 NServiceBus와 비슷한 상황에 처해있었습니다. 나는 이것이 정확히 RavenDB 문제라고 생각하지 않는다. SQL Server 데이터베이스에 쓰는 경우에도 같은 문제가 발생할 수 있습니다.

일반적으로 발생하는 문제는 CreateUpdate 이벤트가 발생하지만 잘못된 순서로 수신되어 처리됩니다. 무엇을해야합니까?

일반적으로 이벤트 처리기는 멱등수가되어야하며 should retry when failed이어야합니다. 따라서 Update이 먼저 수신되면 예외가 발생하고 다시 시도하도록 예약됩니다. 그런 다음 Create이 나오면 Update 시도가 모두 성공합니다.

Update 이벤트에 대한 처리기에서 특히 차단 및 대기하는 것은 권장되지 않습니다. 이들 중 여러 개가 있으면 모든 작업자 스레드를 차단하고 Create 이벤트가 절대로 나오지 않을 수 있기 때문입니다.