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

Posted

技术标签:

【中文标题】写入 RavenDb 后立即读取它会返回不一致的数据【英文标题】:Reading from RavenDb immediately after writing to it returns inconsistent data 【发布时间】:2011-12-19 16:40:15 【问题描述】:

我有一个协调过程,其中通过后台线程定期从外部 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 的实体。谁能看到这里有什么问题?

谢谢,

【问题讨论】:

【参考方案1】:

这是 Raven 采用的最终一致性模型的结果。由于写入而对索引的更新是异步发生的,因此不久之后执行读取可能会返回陈旧的结果。您可以更改您的查询以获得这样的非陈旧结果:

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

Ayende covers in this blog post 还有其他几个选项。

【讨论】:

感谢您的快速响应,这确实是问题所在!

以上是关于写入 RavenDb 后立即读取它会返回不一致的数据的主要内容,如果未能解决你的问题,请参考以下文章

CloudKit 是强一致还是最终一致?

Cassandra 写入后读取与 LOCAL_QUORUM 不一致

Java socket 读取后立即写入

mysql写入后立即读取数据?

非阻塞方式socket send()返回大小和实际发送大小不一致

使用 Windows Azure 上嵌入的 RavenDB 写入日志文件失败