7

調整プロセスがあり、バックグラウンドスレッドによって、外部WebサービスからオブジェクトIDのリストを定期的に取得し、欠落しているエンティティを埋め込みRavenDbデータベースに追加しようとします。このプロセスを実行するループは次のとおりです。

foreach (var pageId in listOfPageIds)
{
    if ( _contentService.GetPageByPageId(pageId) == null)
    {
        _contentService.AddPage(pageId);
    }
}

GetPageByPageId()およびの実装は次のAddPage()とおりです。

public Page GetPageByPageId(string pageId)
{
    using (var session = DocumentStore.OpenSession())
    {
        return session.Query<Page>().FirstOrDefault(page => page.PageId == pageId);
    }
}

public bool AddPage(string pageId)
{
    var page = GetPageByPageId(pageId);
    if (page != null)
    {
        return false;
    }
    using (var session = DocumentStore.OpenSession())
    {
        var newPage = new Page() {PageId = pageId};
        session.Store(newPage);
        session.SaveChanges();
    }
    return true;
}

問題は、リストに重複するIDがある場合、最初のIDを追加してそのIDを再度チェックすると、結果が空として返されることです。新しく追加されたエンティティを登録するファイナライズステップが欠落しているようです。後で別のスレッドからセットをクエリすると、その指定されたIDを持つエンティティが返されます。誰かがここで問題が何であるかを見ることができますか?

ありがとう、

4

1 に答える 1

18

これは、Raven が採用する結果整合性モデルの結果です。書き込みの結果としてのインデックスへの更新は非同期で行われるため、直後に読み取りを実行すると古い結果が返される可能性があります。次のようにクエリを変更して、古くない結果を取得できます。

session.Query<Page>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).FirstOrDefault(page => page.PageId == pageId)

Ayende がこのブログ投稿で説明している他のオプションがいくつかあります。

于 2011-11-01T17:41:03.017 に答える