nhibernate性能之二级缓存篇

 1.学习目标
   通过进一步学习nhibernate,了解二级缓存在nhiernate中的工作机制以及使用方法
2.开发环境和必要准备
    开发环境为:windows 2003,Visual studio .Net 2005,Sql server 2005 developer edition
  必要准备:学习前五篇nhibernate学习系列Nhibernate学习之起步篇-1  ,Nhibernate学习起步之many-to-one篇 ,Nhibernate学习之many-to-many篇 ,nhibernate学习之三级联(Ternary Associations)篇Nhibernate学习之性能改善1
3.学前分析
   在买电脑的时候,我们经常会看CPU的配置,其中衡量CPU性能的一项指标为二级缓存-Level 2 Cache,二级缓存越大,CPU性能越高。这是为什么,大家知道CPU的处理速度非常快,比在内存(memory)中的操作快上很多倍,这样在系统运行的时候,势必会造成一定的瓶颈效应,在内存和CPU之间加上一块处理速度在内存和处理器之间的介质-高速缓存,可以起到平衡的作用,每次CPU都试图先从高速缓存中读取数据,如果没有的话,再去内存中读取,一般CPU对高速缓存的命中率都在90%以上,所以大大提高了性能。在内存和磁盘之间加上一个高速缓存也可提高系统的新性能,减少对磁盘的IO次数
4.如何在nhibernate中启动二级缓存
   在nhiernate中的ISession对象中,已经存在了一级缓存,但是在ISession级别的,我们从上一节可以看出,ISession对象应该是尽早释放的,那依赖它的一级缓存会在它销毁的地时候销毁,所以一级缓存命中率比较低。而ISessionFactory对象推荐为不频繁创建,非常适用于Cache的使用,那这里的二级缓存正是ISessionFactory级别的。
  要想在nhibernate中启用二级缓存,请在hibernate.cfg.xml中添加如下代码:

None.gif < property  name ="hibernate.cache.provider_class" > NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache </ property >
None.gif        
< property  name ="expiration" > 120 </ property >

NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache还可以替换为NHibernate.Caches.Prevalence.PrevalenceCacheProvider, NHibernate.Caches.Prevalence,代表缓存的实现类,在bin目录中有这样两个dll
NHibernate.Caches.SysCache.dll,NHibernate.Caches.Prevalence.dll用哪个就把哪个拷贝到应用程序的bin目录下 
 expiration代表缓存过期时间,单位S
设置完后,还需要在对象的映射文件中配置二级缓存的策略,比如我在User.hbm.xml中如下配置

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
< hibernate-mapping  xmlns ="urn:nhibernate-mapping-2.2" >
None.gif  
< class  name ="NhibernateSample1.User,NhibernateSample1"  table ="Users"  lazy ="false" >
None.gif    
< cache  usage ="read-write" />
None.gif    
< id  name ="Id"  column ="Id"  unsaved-value ="0" >
None.gif      
< generator  class ="native"   />
None.gif    
</ id >
None.gif    
< property  name ="Name"  column ="Name"  type ="string"  length ="64"  not-null ="true"  unique ="true" ></ property >
None.gif    
< property  name ="Pwd"   column ="Pwd"   type ="string"  length ="64"  not-null ="true" ></ property >
None.gif    
< many-to-one  name ="Role"   class ="NhibernateSample1.Role,NhibernateSample1"  column ="RoleID" ></ many-to-one >
None.gif   
</ class >
None.gif
</ hibernate-mapping >

NHibernateHelper.cs

None.gif using  System;
None.gif
using  System.Data;
None.gif
using  System.Configuration;
None.gif
using  System.Web;
None.gif
using  System.Web.Security;
None.gif
using  System.Web.UI;
None.gif
using  System.Web.UI.WebControls;
None.gif
using  System.Web.UI.WebControls.WebParts;
None.gif
using  System.Web.UI.HtmlControls;
None.gif
using  NHibernate;
None.gif
using  NHibernate.Cfg;
None.gif
None.gif
None.gif
namespace  WebApp
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public sealed class NHibernateHelper
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private const string CurrentSessionKey = "nhibernate.current_session";
InBlock.gif        
private static readonly ISessionFactory sessionFactory;
InBlock.gif
InBlock.gif        
static NHibernateHelper()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
string cfgPath = @"E:\my project\nhibernate study\simple4\NHibernateStudy1\NhibernateSample1\hibernate.cfg.xml";
InBlock.gif            sessionFactory 
= new NHibernate.Cfg.Configuration().Configure(cfgPath).BuildSessionFactory();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static ISession GetCurrentSession()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            HttpContext context 
= HttpContext.Current;
InBlock.gif            ISession currentSession 
= context.Items[CurrentSessionKey] as ISession;
InBlock.gif
InBlock.gif            
if (currentSession == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                currentSession 
= sessionFactory.OpenSession();
InBlock.gif                context.Items[CurrentSessionKey] 
= currentSession;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
return currentSession;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void CloseSession()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            HttpContext context 
= HttpContext.Current;
InBlock.gif            ISession currentSession 
= context.Items[CurrentSessionKey] as ISession;
InBlock.gif
InBlock.gif            
if (currentSession == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
// No current session
InBlock.gif
                return;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            currentSession.Close();
InBlock.gif            context.Items.Remove(CurrentSessionKey);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void CloseSessionFactory()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (sessionFactory != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                sessionFactory.Close();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif

页面代码:
None.gif  System.Diagnostics.Stopwatch sw  =   new  System.Diagnostics.Stopwatch();
None.gif            sw.Start();
None.gif            ISession session 
=  NHibernateHelper.GetCurrentSession();
None.gif            ITransaction tra 
=  session.BeginTransaction();
None.gif            session.Load(
typeof (NhibernateSample1.User),  1 );
None.gif            tra.Commit();           
None.gif            sw.Stop();
None.gif            Response.Write(sw.ElapsedTicks
+ " <br> " );
None.gif            sw.Reset();
None.gif            sw.Start();
None.gif            session 
=  NHibernateHelper.GetCurrentSession();
None.gif            tra 
=  session.BeginTransaction();
None.gif            session.Load(
typeof (NhibernateSample1.User),  1 );
None.gif            tra.Commit();           
None.gif            sw.Stop();
None.gif            Response.Write(sw.ElapsedTicks 
+   " <br> " );
None.gif            sw.Reset();
None.gif            sw.Start();
None.gif            session 
=  NHibernateHelper.GetCurrentSession();
None.gif            session.Close();
None.gif            sw.Stop();
None.gif            Response.Write(sw.ElapsedTicks 
+   " <br> " );
第一次运行,用SQL事件探查器,结果为

从截图中的SQL语句看,第一次从数据库中加在User数据
第二次

从图中可以看出,第二次加载User对象,并没有从数据中获取数据,而是将没有设置Cache的Role信息从User里面获取。
当然在利用缓存的时候,缓存不会知道另外一个进程存储的实体发生变化,应该自己建立一些策略来及时地更新缓存快照。而且当ISessionFactory销毁的时候,二级缓存也会随之销毁,这也是应用的时候,应该注意的。今天先写到这,有点困了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值