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 回答