RavenDB - 缓存? "Staleness" ?为什么更新的文档不会随更新一起返回?



我正试图将我自己的博客从MSSQL/EF转换为RavenDB,到目前为止,这在很大程度上是无痛的,但我怀疑这是"过时的索引"或过于自信的缓存,但我无法得到任何实际的答案。当我不知道实际问题是什么时,演示比解释更容易

设置:

// Basic example class
public class ExampleClass{
    public int ID {get;set;}
    public string Value {get;set;}
}
// Once at application startup:
_docStore = new DocumentStore {
    Url = "http://localhost:8080",
    DefaultDatabase = "exampleDB",
    Credentials = new NetworkCredential("userfoo","passbar"),
    };            
_docStore.Initialize();
// Querying data:    
using (var session = _docStore.OpenSession())
{
    var results = _session.Query<ExampleClass>().ToList();        
    foreach(var result in results)
    {
        Console.WriteLine(string.Format("ID #{0}: {1}",
          result.ID, result.Value));
    }
}

问题是:每当我通过_docStore会话以编程方式更新文档时,一切都很正常。当我在外部编辑数据时(来自另一个客户端,在RavenDB管理工作室等),文档更新不会返回。这里有一些例子。


1)数据库中的初始值

数据库中的文档:

  • ExampleClass/1{"ID":1,"Value":"foo",}
  • ExampleClass/2{"ID":2,"Value":"bar",}

运行查询;控制台结果:

  • ID:foo
  • ID#2:bar

2)通过_docStore会话将ExampleClass/2值更新为"BAR"后

数据库中的文档:

  • ExampleClass/1{"ID":1,"Value":"foo",}
  • ExampleClass/2{"ID":2,"Value":"BAR",}

运行查询;控制台结果:

  • ID:foo
  • ID#2:BAR

3)通过RavenDB工作室将ExampleClass/2值更新为"bah"后

数据库中的文档:

  • ExampleClass/1{"ID":1,"Value":"foo",}
  • ExampleClass/2{"ID":2,"Value":"bah",}

运行查询;控制台结果:

  • ID:foo
  • ID#2:BAR

4)通过RavenDB工作室添加ExampleClass/3后

数据库中的文档:

  • ExampleClass/1{"ID":1,"Value":"foo",}
  • ExampleClass/2{"ID":2,"Value":"bah",}
  • ExampleClass/3{"ID":3,"Value":"垃圾邮件",}

运行查询;控制台结果:

  • ID:foo
  • ID#2:BAR
  • ID#3:垃圾邮件

5)通过RavenDB工作室删除ExampleClass/2后

数据库中的文档:

  • ExampleClass/1{"ID":1,"Value":"foo",}
  • ExampleClass/3{"ID":3,"Value":"垃圾邮件",}

运行查询;控制台结果:

  • ID:foo
  • ID#3:垃圾邮件

6)通过RavenDB工作室更改ExampleClass/3值后

数据库中的文档:

  • ExampleClass/1{"ID":1,"Value":"foo",}
  • ExampleClass/3{"ID":3,"Value":"SPAM",}

运行查询;控制台结果:

  • ID:foo
  • ID#3:垃圾邮件

6)通过RavenDB工作室添加ExampleClass/4后

数据库中的文档:

  • ExampleClass/1{"ID":1,"Value":"foo",}
  • ExampleClass/3{"ID":3,"Value":"SPAM",}
  • ExampleClass/4{"ID":4,"Value":"bar",}

运行查询;控制台结果:

  • ID:foo
  • ID#3:垃圾邮件
  • ID#4:bar

*7)初始化新的DocumentStore后(没有数据更改)*

数据库中的文档:

  • ExampleClass/1{"ID":1,"Value":"foo",}
  • ExampleClass/3{"ID":3,"Value":"SPAM",}
  • ExampleClass/4{"ID":4,"Value":"bar",}

运行查询;控制台结果:

  • ID:foo
  • ID#3:垃圾邮件
  • ID#4:bar

希望这能很好地表明哪里出了问题。添加和删除整个文档反映得很好,但在第一次加载之后会完全忽略更新,这让我怀疑是缓存而不是"过时的索引"。。。但我尝试过这样的事情,但没有运气:

// After initialising document store:
_docStore.DisableAggressiveCaching();
_docStore.DatabaseCommands.DisableAllCaching();
_docStore.Conventions.DefaultQueryingConsistency =
  ConsistencyOptions.QueryYourWrites;
// Whenever opening a new session:
_session.Advanced.DatabaseCommands.DisableAllCaching();
_session.Advanced.AllowNonAuthoritativeInformation = false;                
// When querying:
var result = _session.Query<ExampleClass>()
  .Customize(x=>x.WaitForNonStaleResults())
  .ToList();

什么!$#*发生了什么?为什么RavenDB讨厌我?

RavenDB正在进行缓存,但它是通过检查etag来进行缓存的,所以您不应该看到这种情况。你是否可能总是使用一个会话?

你能试着复制这个吗?

看起来docStore.OOpenSession()总是返回相同的会话,这与Oren的建议相匹配。使用当前的(1.0.701)RavenDB库解决了这个问题。

最新更新