2010-09-02 118 views
2

我在FluentNHibernate启用2级缓存:NHibernate的查询缓存到数据库

Fluently.Configure() 
      .Database(MsSqlConfiguration.MsSql2005 
      .ConnectionString(connectionString) 
      .Cache(c => c.ProviderClass<SysCacheProvider>().UseQueryCache()) 
      ) 
      .Mappings(m => m.FluentMappings.AddFromAssemblyOf<PersonMap>()); 

我的映射如下:

public PersonMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.Name); 
     Cache.ReadWrite(); 
    } 

当我打电话从我的仓库的人,我运行:

var query = session.GetSession().CreateCriteria<Person>("p") 
     .Add(Expression.Eq("p.Org.Id", orgRep.GetOrg().Id)); 
    query.SetCacheable(true); 
    return query.List<Person>().AsQueryable<Person>(); 

当我启动应用程序的一切(包括缓存)工作正常。我的第一个查询会打到数据库,但后面的查询不会。保存人员时出现问题。人保存如下:

public virtual void Save(Person p) 
{ 
    if (p.Id > 0 && session.GetSession().Get<Person>(p.Id).Org != orgRep.GetOrg()) 
      throw new SecurityException("Organization mismatch"); 
    session.GetSession().Merge(p); 
    session.GetSession().Flush(); 
} 

保存工程,但之后缓存没有。查询将始终打到数据库。通过nhibernate日志说:

DEBUG - Checking query spaces for up-to-dateness [[Person]] 
DEBUG - Fetching object 'NHibernate-Cache:UpdateTimestampsCache:[Person]@1639794674' from the cache. 
DEBUG - cached query results were not up to date for: sql: SELECT this_.Id as Id0_0_, this_.Name as Name0_0_, this_.Org_id as Org5_0_0_ FROM [Person] this_ WHERE this_.Org_id = ?; parameters: ['1']; first row: 0 

我在做什么错了?

+0

http://opensource.atlassian.com/projects/hibernate/browse/HHH-3339虽然它在会话级别,但此错误文章看起来类似。如果我在刷新后重置SessionFactory,缓存将再次开始工作。但重置SessionFactory会重置所有二级缓存。在保存后在同一个会话工厂中执行相同的查询时,是否可能会出现时间戳错误? – 2010-09-03 05:55:21

+0

没有人有任何建议可能会出现什么问题吗? – 2010-09-07 06:43:17

+0

A [更详细的答案](/ a/14301438/1178314)现在可用于near dup问题。 – 2016-03-08 09:10:14

回答

0

尝试在会话中使用块实例化显式事务。这篇文章看起来很相关: - http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions

+0

你很好回答了这个问题。其实我认为我们最终通过使用交易得到了它。使用事务对二级缓存至关重要。 – 2012-03-23 07:06:51