Чтение из RavenDB сразу после записи в него возвращает противоречивые данные

#c# #database #ravendb #document-database

#c# #База данных #ravendb #документ-база данных

Вопрос:

У меня есть процесс согласования, в котором фоновый поток периодически извлекает список идентификаторов объектов из внешнего веб-сервиса и пытается добавить недостающие объекты во встроенную базу данных 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;
}
 

Проблема в том, что если список имеет повторяющиеся идентификаторы, то после добавления первого идентификатора и повторной проверки этого идентификатора результат возвращается как пустой. Это похоже на то, как если бы отсутствовал этап завершения, который зарегистрировал бы вновь добавленный объект. Если я запрашиваю набор из другого потока позже, возвращается объект с этим заданным идентификатором. Кто-нибудь может понять, в чем здесь проблема?

Спасибо,

Ответ №1:

Это результат возможной модели согласованности, которую использует Raven. Обновления индексов в результате записи происходят асинхронно, и поэтому возможно, что выполнение чтения вскоре после этого вернет устаревшие результаты. Вы можете изменить свой запрос, чтобы получить не устаревшие результаты, подобные этому:

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

Есть несколько других вариантов, которые Ayende рассматривает в этом сообщении в блоге.

Комментарии:

1. Спасибо за быстрый ответ, это действительно была проблема!