写入后立即从RavenDb读取返回不一致的数据

时间:2021-05-20 23:10:28

I have a reconciliation process where by a background thread that periodically retrieves a list of object ids from an external webservice and attempts to add the missing entities to an embedded RavenDb database. The loop that performs this process is the following:

我有一个协调过程,由后台线程定期从外部Web服务检索对象ID列表,并尝试将缺少的实体添加到嵌入式RavenDb数据库。执行此过程的循环如下:

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

the implementation of the GetPageByPageId() and AddPage() are as follows:

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;
}

The problem is that if the list has duplicate ids, once it adds the first id and checks for that id again, the result comes back as empty. It is as if a finalization step is missing that would register the newly added entity. If I query the set from a different thread at a later time, the entity with that given id is returned. Can anyone see what the issue is here?

问题是如果列表有重复的id,一旦它添加第一个id并再次检查该id,结果将返回为空。就好像缺少一个注册新添加的实体的终结步骤。如果我稍后从另一个线程查询该集合,则返回具有该给定id的实体。任何人都可以看到这里的问题是什么?

thanks,

谢谢,

1 个解决方案

#1


19  

This is a result of the eventual consistency model that Raven adopts. Updates to the indexes as a result of writes happen asynchronously and therefore it is possible that performing a read shortly after will return stale results. You can alter your query to get non-stale results like this:

这是Raven采用的最终一致性模型的结果。由于写入而对索引的更新是异步发生的,因此很快就会执行读取将返回过时的结果。您可以更改查询以获得非陈旧的结果,如下所示:

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

There's a couple of other options that Ayende covers in this blog post.

Ayende在这篇博客文章中介绍了其他几个选项。

#1


19  

This is a result of the eventual consistency model that Raven adopts. Updates to the indexes as a result of writes happen asynchronously and therefore it is possible that performing a read shortly after will return stale results. You can alter your query to get non-stale results like this:

这是Raven采用的最终一致性模型的结果。由于写入而对索引的更新是异步发生的,因此很快就会执行读取将返回过时的结果。您可以更改查询以获得非陈旧的结果,如下所示:

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

There's a couple of other options that Ayende covers in this blog post.

Ayende在这篇博客文章中介绍了其他几个选项。