如何将所有内容加载到nhibernate 2级缓存中?

3
我有一个使用nhibernate和SQL Server的asp.net-mvc网站,其中有几个页面非常慢,因为它们需要查询大约25个不同表格的视图。如果我不进行大型连接,则需要一段时间,如果进行多个查询,仍需花费一段时间。
由于我的数据库很重(轻写入),因此我想看看是否有一种好的方法可以将整个对象图形(我的服务器有足够的内存)加载到第二级缓存中,以便我可以确信它很少会访问数据库。我正在使用
  NHibernate.Caches.SysCache.SysCacheProvider

作为第二级缓存(非分布式缓存),这个想法有什么缺陷?有没有推荐的做法?
2个回答

2
你正在缓存查询结果,但不是你的实体(它们是分开缓存的)。 仅缓存查询结果会存储ID;如果你没有同时缓存实体,那么每返回一个实体都会发出一个查询(这通常是不好的)。 MyDTO类的默认表名是MyDTO,所以它就在那里找。 看起来像是按ID查询,对于这种情况,不应该使用松散的命名查询,而应该使用适当的加载器。(请参阅17.4。用于加载的自定义SQL) 一旦设置了加载器和实体缓存,你只需使用session.Get(id)检索对象,它将使用二级缓存,只要你所有的工作都在事务内进行,这是推荐的做法。

我完全不理解你的回答,你有一些例子或链接作为参考吗? - leora
http://www.klopfenstein.net/lorenz.aspx/using-syscache-as-secondary-cache-in-nhibernate - Richa Jain

1

二级缓存始终与Session Factory对象相关联。在运行事务时,它在Session Factory级别加载对象,以便这些对象将对整个应用程序可用,而不仅仅是单个用户。由于对象已经加载到缓存中,因此每当查询返回一个对象时,就无需进行数据库事务。

必须为要缓存的每个单独实体类启用并配置二级缓存。因此,需要启用缓存来缓存映射到15个表的15个对象。

在XML中,这是在元素内完成的:

<cache usage="read-write"/>

在Fluent NHibernate(非自动映射)中,它是在ClassMap构造函数或您放置其余映射代码的任何位置完成的:
Cache.ReadWrite().Region("Configuration");

从这里开始,这取决于数据库的大小和负载,以及新数据必须存在的方式。

如果数据库相对较小且写入较少,则可以在每次写入/更新时更新缓存。

ISession.Clear();
ReloadCache();

如果数据库非常庞大: 并且您每天只需更新一次数据库,比如在12点,并将“新”数据保存在缓存中一天,那么您也可以。重新加载时,一些用户会出现延迟峰值。
这是一个例子: http://www.codeproject.com/Articles/529016/NHibernate-Second-Level-Caching-Implementation 如果您的数据库非常庞大且用户必须获取更新的数据,则必须手动更新缓存中的数据。
Database db =   new Database (); 
Transaction tx = db.BeginTransaction (); 
try 
{ 
// Read from the cache 
MyEntity1 entity1 = cache.Get <MyEntity1> ("pk of entity1"); 
// Cache is not read from the database 
 if (entity1 ==   null) entity1 = db.Get <MyEntity1> ("pk of entity1"); 

// Entity1 processing 

updated = db.Update, (entity1); / / entity1 update saved to the database 
 if (updated) cache.Put (entity1); / / database update successfully, the update cache 

// Transaction processing 

tx.commit (); 
} 
catch 
{ 
tx.Rollback (); 
throw; 
}

更多相关信息请查看这里:http://www.databaseskill.com/3093355/


我不明白你的代码在做什么。如果你只想将所有实体初始加载到二级缓存中,为什么需要使用db.Update呢? - leora
你能否提供更多关于你的应用程序的细节,包括数据在读取时需要多新鲜。上面的代码试图展示一种场景,在这种情况下,你需要手动更新已经存在于数据库和缓存中的值。 - Matas Vaitkevicius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接