2013-07-28 59 views
1

我使用RavenDB作爲從域事件填充的非規範化讀取模型。我發現問題,當兩個事件(讓我們稱它們爲「已創建」和「已更新」)在同一時間被非規範化時,在保存Created事件所做的更改之前,會發生由更新事件更新的加載文檔。我已經與解決方案基於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(); 
     }    
    } 

不幸的是第二次調用加載返回null,原因的文件ID已在knownMissingIds領域InMemoryDocumentSessionOperations和服務器發出任何請求。

有沒有其他方式可以等到創建文檔?

回答

2

嗯,我不知道你用於事件處理的是什麼機制,但我一直在類似的情況下,像NServiceBus。我不認爲這完全是一個RavenDB問題。如果您正在寫入SQL Server數據庫,您可能會遇到同樣的問題。

廣義問題是,CreateUpdate事件被觸發,但它們是以錯誤的順序接收和處理的。該怎麼辦?

那麼一般的建議是你的事件處理程序應該是冪等的,並且should retry when failed。因此,如果首先收到Update,它將拋出異常並安排重試。然後Create通過,然後Update重試,一切都很好。

不建議在處理程序中特別阻塞和等待Update事件,因爲如果您有幾個這樣的事件,那麼它們可以阻止所有工作線程,並且事件永遠不會通過。