RavenDB возвращает устаревшие результаты после удаления - PullRequest
4 голосов
/ 03 марта 2012

Кажется, мы убедились, что RavenDB получает устаревшие результаты, даже когда мы используем различные варианты "WaitForNonStaleResults". Ниже приведен полнофункциональный пример кода (написанный как отдельный тест, чтобы вы могли скопировать / вставить его и запустить как есть).

public class Cart
{
  public virtual string Email { get; set; }
}

[Test]
public void StandaloneTestForPostingOnStackOverflow()
{
  var testDocument = new Cart { Email = "test@abc.com" };
  var documentStore = new EmbeddableDocumentStore { RunInMemory = true };
  documentStore.Initialize();

  using (var session = documentStore.OpenSession())
  {
    using (var transaction = new TransactionScope())
    {
      session.Store(testDocument);
      session.SaveChanges();
      transaction.Complete();
    }

    using (var transaction = new TransactionScope())
    {
      var documentToDelete = session
        .Query<Cart>()
        .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
        .First(c => c.Email == testDocument.Email);

      session.Delete(documentToDelete);
      session.SaveChanges();
      transaction.Complete();
    }

    RavenQueryStatistics statistics;

    var actualCount = session
      .Query<Cart>()
      .Statistics(out statistics)
      .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
      .Count(c => c.Email == testDocument.Email);

    Assert.IsFalse(statistics.IsStale);
    Assert.AreEqual(0, actualCount);
  }
}

Мы перепробовали все варианты WaitForNonStaleResults, и никаких изменений не произошло. Ожидание не устарелых результатов работает нормально для обновления, но не для удаления.

Обновление

Некоторые вещи, которые я пробовал:

  1. Использование отдельных сеансов для каждого действия. Результат: без разницы. Те же успехи и неудачи.

  2. Помещение Thread.Current.Sleep(500) перед последним запросом. Итог: успех. Если я сплю нить в течение полсекунды, счетчик возвращается на ноль, как и должен.

Ответы [ 3 ]

1 голос
/ 02 апреля 2012

Re: мой комментарий выше к устаревшим результатам, AllowNonAuthoritiveInformation не работал.Необходимость помещать WaitForNonStaleResults в каждый запрос, который является обычным «ответом» на эту проблему, ощущается как массивный «запах кода» (насколько я обычно ненавижу этот термин, он кажется совершенно уместным здесь).

Единственное реальное решение, которое я нашел до сих пор, это:

var store = new DocumentStore(); // do whatever
store.DatabaseCommands.DisableAllCaching();

Производительность соответственно страдает, но я думаю, что более медленная производительность гораздо менее греховна, чем ненадежная, если не совсем неточные результаты.

1 голос
/ 13 мая 2015

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

session.DocumentStore.DefaultQueryingConsistency = ConsistencyOptions.AlwaysWaitForNonStaleResultsAsOfLastWrite;

Это позволило мне не настраивать каждый запрос после. Тем не менее, я считаю, что это работает только для запросов. Это определенно не работает с патчами, как я выяснил в ходе тестирования.

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

session.DocumentStore.DefaultQueryingConsistency = ConsistencyOptions.None;
0 голосов
/ 04 марта 2012

Проблема не связана с удалением, она связана с использованием TransactionScope. Проблема в том, что транзакция DTC завершается асинхронно.

Чтобы решить эту проблему, вам нужно позвонить:

 session.Advanced.AllowNonAuthoritiveInformation = false;

Что заставит RavenDB ждать завершения транзакции.

...