RavenDB在删除后返回陈旧的结果

RavenDB在删除后返回陈旧的结果,ravendb,Ravendb,我们似乎已经验证了RavenDB正在得到过时的结果,即使我们使用了各种各样的“WaitForNonSaleResults”。以下是完整功能的示例代码(作为独立测试编写,以便您可以复制/粘贴它并按原样运行) 公共类购物车 { 公共虚拟字符串电子邮件{get;set;} } [测试] public void Standalonetest for PostingOnStackOverflow() { var testDocument=新购物车{电子邮件=”test@abc.com" }; var do

我们似乎已经验证了RavenDB正在得到过时的结果,即使我们使用了各种各样的“WaitForNonSaleResults”。以下是完整功能的示例代码(作为独立测试编写,以便您可以复制/粘贴它并按原样运行)

公共类购物车
{
公共虚拟字符串电子邮件{get;set;}
}
[测试]
public void Standalonetest for PostingOnStackOverflow()
{
var testDocument=新购物车{电子邮件=”test@abc.com" };
var documentStore=new embeddedabledocumentstore{RunInMemory=true};
初始化();
使用(var session=documentStore.OpenSession())
{
使用(var transaction=new TransactionScope())
{
session.Store(testDocument);
session.SaveChanges();
transaction.Complete();
}
使用(var transaction=new TransactionScope())
{
var documentToDelete=会话
.Query()
.Customize(x=>x.WaitForNonSalesultsAsoflastWrite())
.首先(c=>c.Email==testDocument.Email);
删除(documentToDelete);
session.SaveChanges();
transaction.Complete();
}
拉文奎尔统计;
var actualCount=会话
.Query()
.统计数字(外统计数字)
.Customize(x=>x.WaitForNonSalesultsAsoflastWrite())
.Count(c=>c.Email==testDocument.Email);
Assert.IsFalse(statistics.IsStale);
Assert.AreEqual(0,实际计数);
}
}
我们已经尝试了WaitForNonSaleResults的每一种口味,没有任何变化。等待不过时的结果似乎对更新很有效,但对删除却不起作用

更新

我尝试过的一些事情:

  • 对每个操作使用单独的会话。结果:无差异。同样的成功和失败

  • Thread.Current.Sleep(500)
    放在最终查询之前。结果:成功。如果我将线程休眠半秒钟,计数会像它应该的那样返回零


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

    要解决此问题,您需要做的是调用:

     session.Advanced.AllowNonAuthoritiveInformation = false;
    

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

    Re:我上面对陈旧结果的评论,AllowOnAuthoritiveInformation不起作用。需要在每个查询中放入WaitForNonSaleResults,这是这个问题的常见“答案”,感觉就像是一种巨大的“代码气味”(虽然我通常非常讨厌这个术语,但在这里似乎完全合适)

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

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

    性能也因此受到影响,但我认为,如果不是完全不准确的结果,那么性能变慢远比不可靠更是罪过。

    这是一个老问题,但我最近也遇到了这个问题。我可以通过更改会话使用的
    DocumentStore
    上的约定来解决此问题,以使会话在上次写入时等待非过期:

    session.DocumentStore.DefaultQueryingConsistency = ConsistencyOptions.AlwaysWaitForNonStaleResultsAsOfLastWrite;
    
    这样,我就不必自定义之后运行的每个查询。尽管如此,我相信这只适用于查询。正如我通过测试发现的那样,它在补丁上肯定不起作用

    我也会注意这一点,只在需要的代码中使用它,因为它可能会导致性能问题。您可以通过以下操作将存储设置回其默认值:

    session.DocumentStore.DefaultQueryingConsistency = ConsistencyOptions.None;
    

    testDocument在哪里声明?您确定documentToDelete不为null吗?是否可能需要关闭会话并使用新会话执行查询?testDocument在函数的第一行初始化。至于新会话,我不必打开新会话来获取当前查询结果,但无论如何,我已经尝试过了。我将编辑这篇文章以包含更多的信息和观察结果。有意思的是,睡半秒钟是有效的。我唯一能想到的另一件事是它要么是一个bug,要么你需要一个更好的索引。您使用的是什么版本的RavenDB?非常感谢您对这个问题的关注。我们非常感谢!不幸的是,添加这一行并没有解决问题。两次计时之间仍然存在脱节。我们还添加了对
    ExecuteAllPendingLazyOperations
    的调用,希望这可能会有所帮助,但事实并非如此。我知道事务是异步完成的,但是有没有办法强制请求等待挂起的事务完成?我认为这就是
    waitfornonsale…
    函数的目的。我这里也有相反的问题,不管我做什么,陈旧的结果都会回来,除非我初始化一个新的文档存储(完全不可接受的解决方案)。如果添加或删除了某些内容,它会很好地处理,但是任何更新的内容都会返回陈旧的内容,就好像在创建新的文档存储之前从未发生过更新一样。3天浪费在这上面了。。。啊。。。
    session.DocumentStore.DefaultQueryingConsistency = ConsistencyOptions.None;