RavenDB在删除后返回过时的结果

时间:2012-03-02 22:40:33

标签: ravendb

我们似乎已经证实,即使我们使用各种风格的“WaitForNonStaleResults”,RavenDB也会变得过时。以下是功能齐全的示例代码(作为独立测试编写,以便您可以复制/粘贴它并按原样运行)。

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 个答案:

答案 0 :(得分:1)

Re:我上面关于过时结果的评论,AllowNonAuthoritiveInformation无效。需要在每个查询中放置WaitForNonStaleResults,这是这个问题的常见“答案”,感觉就像一个巨大的“代码味道”(就像我通常讨厌这个术语一样,这似乎完全合适)。

到目前为止,我找到的唯一真正的解决方案是:

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

性能受到相应的影响,但我认为,如果不是完全不准确的结果,那么较慢的性能远不是不可靠的。

答案 1 :(得分:1)

这是一个老问题,但我最近也遇到了这个问题。我能够通过改变会话使用的DocumentStore上的约定来解决它,使其在上次写入时等待非陈旧:

session.DocumentStore.DefaultQueryingConsistency = ConsistencyOptions.AlwaysWaitForNonStaleResultsAsOfLastWrite;

这使得我不必自定义每次运行的查询。也就是说,我相信这只适用于查询。正如我通过测试所发现的那样,它肯定不适用于补丁。

我也会小心这一点,只使用它所需的代码,因为它可能会导致性能问题。您可以使用以下内容将商店设置回其默认值:

session.DocumentStore.DefaultQueryingConsistency = ConsistencyOptions.None;

答案 2 :(得分:0)

问题与删除无关,与使用TransactionScope有关。这里的问题是DTC事务以异步方式完成。

要解决此问题,您需要做的是致电:

 session.Advanced.AllowNonAuthoritiveInformation = false;

这将迫使RavenDB等待事务完成。