服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

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中添加如下代码:
nhibernate性能之二级缓存篇(图一)
<property name="hibernate.cache.provider_class">nhibernate.caches.syscache.syscacheprovider, nhibernate.caches.syscache</property>
nhibernate性能之二级缓存篇(图一)        <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中如下配置

nhibernate性能之二级缓存篇(图一)<?xml version="1.0" encoding="utf-8" ?>
nhibernate性能之二级缓存篇(图一)<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
nhibernate性能之二级缓存篇(图一)  <class name="nhibernatesample1.user,nhibernatesample1" table="users" lazy="false">
nhibernate性能之二级缓存篇(图一)    <cache usage="read-write"/>
nhibernate性能之二级缓存篇(图一)    <id name="id" column="id" unsaved-value="0">
nhibernate性能之二级缓存篇(图一)      <generator class="native" />
nhibernate性能之二级缓存篇(图一)    </id>
nhibernate性能之二级缓存篇(图一)    <property name="name" column="name" type="string" length="64" not-null="true" unique="true"></property>
nhibernate性能之二级缓存篇(图一)    <property name="pwd"  column="pwd"  type="string" length="64" not-null="true"></property>
nhibernate性能之二级缓存篇(图一)    <many-to-one name="role"  class="nhibernatesample1.role,nhibernatesample1" column="roleid"></many-to-one>
nhibernate性能之二级缓存篇(图一)   </class>
nhibernate性能之二级缓存篇(图一)</hibernate-mapping>

nhibernatehelper.cs

nhibernate性能之二级缓存篇(图一)using system;
nhibernate性能之二级缓存篇(图一)using system.data;
nhibernate性能之二级缓存篇(图一)using system.configuration;
nhibernate性能之二级缓存篇(图一)using system.web;
nhibernate性能之二级缓存篇(图一)using system.web.security;
nhibernate性能之二级缓存篇(图一)using system.web.ui;
nhibernate性能之二级缓存篇(图一)using system.web.ui.webcontrols;
nhibernate性能之二级缓存篇(图一)using system.web.ui.webcontrols.webparts;
nhibernate性能之二级缓存篇(图一)using system.web.ui.htmlcontrols;
nhibernate性能之二级缓存篇(图一)using nhibernate;
nhibernate性能之二级缓存篇(图一)using nhibernate.cfg;
nhibernate性能之二级缓存篇(图一)
nhibernate性能之二级缓存篇(图一)
nhibernate性能之二级缓存篇(图一)namespace webapp
nhibernate性能之二级缓存篇(图二)nhibernate性能之二级缓存篇(图三)nhibernate性能之二级缓存篇(图四){
nhibernate性能之二级缓存篇(图五)    public sealed class nhibernatehelper
nhibernate性能之二级缓存篇(图六)nhibernate性能之二级缓存篇(图七)    nhibernate性能之二级缓存篇(图四){
nhibernate性能之二级缓存篇(图五)        private const string currentsessionkey = "nhibernate.current_session";
nhibernate性能之二级缓存篇(图五)        private static readonly isessionfactory sessionfactory;
nhibernate性能之二级缓存篇(图五)
nhibernate性能之二级缓存篇(图五)        static nhibernatehelper()
nhibernate性能之二级缓存篇(图六)nhibernate性能之二级缓存篇(图七)        nhibernate性能之二级缓存篇(图四){
nhibernate性能之二级缓存篇(图五)            string cfgpath = @"e:/my project/nhibernate study/simple4/nhibernatestudy1/nhibernatesample1/hibernate.cfg.xml";
nhibernate性能之二级缓存篇(图五)            sessionfactory = new nhibernate.cfg.configuration().configure(cfgpath).buildsessionfactory();
nhibernate性能之二级缓存篇(图八)        }
nhibernate性能之二级缓存篇(图五)
nhibernate性能之二级缓存篇(图五)        public static isession getcurrentsession()
nhibernate性能之二级缓存篇(图六)nhibernate性能之二级缓存篇(图七)        nhibernate性能之二级缓存篇(图四){
nhibernate性能之二级缓存篇(图五)            httpcontext context = httpcontext.current;
nhibernate性能之二级缓存篇(图五)            isession currentsession = context.items[currentsessionkey] as isession;
nhibernate性能之二级缓存篇(图五)
nhibernate性能之二级缓存篇(图五)            if (currentsession == null)
nhibernate性能之二级缓存篇(图六)nhibernate性能之二级缓存篇(图七)            nhibernate性能之二级缓存篇(图四){
nhibernate性能之二级缓存篇(图五)                currentsession = sessionfactory.opensession();
nhibernate性能之二级缓存篇(图五)                context.items[currentsessionkey] = currentsession;
nhibernate性能之二级缓存篇(图八)            }
nhibernate性能之二级缓存篇(图五)
nhibernate性能之二级缓存篇(图五)            return currentsession;
nhibernate性能之二级缓存篇(图八)        }
nhibernate性能之二级缓存篇(图五)
nhibernate性能之二级缓存篇(图五)        public static void closesession()
nhibernate性能之二级缓存篇(图六)nhibernate性能之二级缓存篇(图七)        nhibernate性能之二级缓存篇(图四){
nhibernate性能之二级缓存篇(图五)            httpcontext context = httpcontext.current;
nhibernate性能之二级缓存篇(图五)            isession currentsession = context.items[currentsessionkey] as isession;
nhibernate性能之二级缓存篇(图五)
nhibernate性能之二级缓存篇(图五)            if (currentsession == null)
nhibernate性能之二级缓存篇(图六)nhibernate性能之二级缓存篇(图七)            nhibernate性能之二级缓存篇(图四){
nhibernate性能之二级缓存篇(图五)                // no current session
nhibernate性能之二级缓存篇(图五)                return;
nhibernate性能之二级缓存篇(图八)            }
nhibernate性能之二级缓存篇(图五)
nhibernate性能之二级缓存篇(图五)            currentsession.close();
nhibernate性能之二级缓存篇(图五)            context.items.remove(currentsessionkey);
nhibernate性能之二级缓存篇(图八)        }
nhibernate性能之二级缓存篇(图五)
nhibernate性能之二级缓存篇(图五)        public static void closesessionfactory()
nhibernate性能之二级缓存篇(图六)nhibernate性能之二级缓存篇(图七)        nhibernate性能之二级缓存篇(图四){
nhibernate性能之二级缓存篇(图五)            if (sessionfactory != null)
nhibernate性能之二级缓存篇(图六)nhibernate性能之二级缓存篇(图七)            nhibernate性能之二级缓存篇(图四){
nhibernate性能之二级缓存篇(图五)                sessionfactory.close();
nhibernate性能之二级缓存篇(图八)            }
nhibernate性能之二级缓存篇(图八)        }
nhibernate性能之二级缓存篇(图八)    }
nhibernate性能之二级缓存篇(图五)
nhibernate性能之二级缓存篇(图九)}
nhibernate性能之二级缓存篇(图一)


页面代码:

nhibernate性能之二级缓存篇(图一) system.diagnostics.stopwatch sw = new system.diagnostics.stopwatch();
nhibernate性能之二级缓存篇(图一)            sw.start();
nhibernate性能之二级缓存篇(图一)            isession session = nhibernatehelper.getcurrentsession();
nhibernate性能之二级缓存篇(图一)            itransaction tra = session.begintransaction();
nhibernate性能之二级缓存篇(图一)            session.load(typeof(nhibernatesample1.user), 1);
nhibernate性能之二级缓存篇(图一)            tra.commit();           
nhibernate性能之二级缓存篇(图一)            sw.stop();
nhibernate性能之二级缓存篇(图一)            response.write(sw.elapsedticks+"<br>");
nhibernate性能之二级缓存篇(图一)            sw.reset();
nhibernate性能之二级缓存篇(图一)            sw.start();
nhibernate性能之二级缓存篇(图一)            session = nhibernatehelper.getcurrentsession();
nhibernate性能之二级缓存篇(图一)            tra = session.begintransaction();
nhibernate性能之二级缓存篇(图一)            session.load(typeof(nhibernatesample1.user), 1);
nhibernate性能之二级缓存篇(图一)            tra.commit();           
nhibernate性能之二级缓存篇(图一)            sw.stop();
nhibernate性能之二级缓存篇(图一)            response.write(sw.elapsedticks + "<br>");
nhibernate性能之二级缓存篇(图一)            sw.reset();
nhibernate性能之二级缓存篇(图一)            sw.start();
nhibernate性能之二级缓存篇(图一)            session = nhibernatehelper.getcurrentsession();
nhibernate性能之二级缓存篇(图一)            session.close();
nhibernate性能之二级缓存篇(图一)            sw.stop();
nhibernate性能之二级缓存篇(图一)            response.write(sw.elapsedticks + "<br>");

第一次运行,用sql事件探查器,结果为

nhibernate性能之二级缓存篇(图十)

点击查看大图


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

nhibernate性能之二级缓存篇(图十一)

点击查看大图


从图中可以看出,第二次加载user对象,并没有从数据中获取数据,而是将没有设置cache的role信息从user里面获取。
当然在利用缓存的时候,缓存不会知道另外一个进程存储的实体发生变化,应该自己建立一些策略来及时地更新缓存快照。而且当isessionfactory销毁的时候,二级缓存也会随之销毁,这也是应用的时候,应该注意的。

扫描关注微信公众号