2017-01-25 114 views
1

我們一直有一個問題,下面的方法,查詢烏鴉分貝的作品,但只有約90%的時間烏鴉查詢只能有時

member.UserId = userService.GivenUsernameGetUserId(command.EmailAddress.ToLower()); 

來解決這個問題,我做了這個醜陋的黑客解決方法這似乎已經解決了這一問題:

member.UserId = userService.GivenUsernameGetUserId(command.EmailAddress.ToLower()); 
System.Threading.Thread.Sleep(1000); 
if (member.UserId.IsNullOrEmpty()) 
{ 
    logger.Error("the userid was not loaded in time"); 
    for (int i = 0; i < 5; i++) 
    {       
     member.UserId = userService.GivenUsernameGetUserId(command.EmailAddress.ToLower()); 
     System.Threading.Thread.Sleep(1000); 
     if (member.UserId.IsNotNullOrEmpty()) 
     { 
      logger.Info("The userid was retrieved in a loop after some delay "); 
      break; 
     } 
    } 
    if (member.UserId.IsNullOrEmpty()) 
    { 
     logger.Error("a loop of 5 cycles was run trying to retrieve the userId but couldn't get it."); 
    } 
} 

有人能看到爲什麼它可能只是有時檢索正確的數據,是否有更好的解決方案,以確保它不停地嘗試,直到它獲取的數據?我在想是否有一些基本的超時設置可以在web.config中設置或什麼的?

+1

在文檔中插入新內容後,是否「無法正常工作」? – Reniuz

+0

不,唯一的前面的陳述是查詢 – Jynn

+2

不知何故,我懷疑你得到陳舊的結果:/ – Reniuz

回答

2

這個問題可能是陳舊的索引:用戶最近被創建,索引沒有機會更新。 (通常這需要毫秒,但對大型數據庫可能需要更長的時間。)

有3件事情可以做,在這裏解決您的問題:

  • 選項1:使基於電子郵件地址,用戶ID 。那麼你根本就不用瞎搞索引。
  • 選項2:您可以按原樣保留用戶標識,但等待非陳舊索引。
  • 選項3:創建用戶時,請等待索引更新。

我將逐一介紹以下這些選項:


選項1:

讓你的用戶ID衆所周知,這樣你就不必用戶索引在所有。

說你的對象叫做User。當你註冊用戶時,你的代碼將如下所示:

public void RegisterUser(string emailAddress) 
{ 
    var user = new User 
    { 
     UserName = emailAddress, 
     ... 
    }; 

    // Give the User a well-known ID, so that we don't have to mess with indexes later. 
    user.Id = "Users/" + emailAddress; 

    ravenSession.Store(user); 
} 

如果你這樣做,你將不必混淆索引。當談到時間來加載用戶:

public string GivenUsernameGetUserId(string userName) 
{ 
    // Look ma, no query needed. 
    return "Users/" + userName; 

    // Or, need to return the User itself? You can use .Load, which will never be stale. 
    // return ravenSession.Load<User>("Users/" + userName); 
} 

這真的是你最好的選擇,而你從來沒有處理指標,因此,你永遠不會有處理過期數據。


選項2

選項2是使用.WaitForNonStaleResults。它在返回結果之前等待索引變爲最新。

public string GivenUsernameGetUserId(string userName) 
{ 
    // Use .WaitForNonStaleResultsAsOfNow() 
    return ravenSession.Query<User>() 
     .Customize(x => x.WaitForNonStaleResultsAsOfNow()) 
     .Where(u => u.UserName == userName) 
     .Select(u => u.Id) 
     .FirstOrDefault(); 
} 

選項3

方案3是等待索引時節省用戶更新。

這需要Raven 3.5或更高版本。

public void RegisterUser(string userName) 
{ 
    ravenSession.Advanced.WaitForIndexesAfterSaveChanges(timeout: TimeSpan.FromSeconds(30)); 
    var user = new User {...}; 
    ravenSession.Store(user); 
    ravenSession.SaveChanges(); // This won't return until the User is stored *AND* the indexes are updated. 
}; 

就個人而言,我推薦使用#1:知名的ID爲您的用戶。此外,即使您實施其他解決方案,我也推薦#3:SaveChanges將等待索引在返回之前更新。這將導致陳舊索引周圍的驚喜減少,所以我一般會推薦它。