我们似乎已经证实,即使我们使用各种风格的“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的每一种风格,并且没有任何变化。等待非陈旧的结果似乎适用于更新,但不适用于删除。
更新
我尝试过的一些事情:
为每个操作使用单独的会话。结果:没有区别。同样的成功并失败。
在最终查询之前放置Thread.Current.Sleep(500)
。结果:成功。如果我把线程睡了半秒钟,那么计数就会回归零点。
答案 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等待事务完成。