zoukankan      html  css  js  c++  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中添加如下代码:

    <property name="hibernate.cache.provider_class">NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache</property>
            
    <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中如下配置

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

    NHibernateHelper.cs

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using NHibernate;
    using NHibernate.Cfg;


    namespace WebApp
    {
        
    public sealed class NHibernateHelper
        
    {
            
    private const string CurrentSessionKey = "nhibernate.current_session";
            
    private static readonly ISessionFactory sessionFactory;

            
    static NHibernateHelper()
            
    {
                
    string cfgPath = @"E:\my project\nhibernate study\simple4\NHibernateStudy1\NhibernateSample1\hibernate.cfg.xml";
                sessionFactory 
    = new NHibernate.Cfg.Configuration().Configure(cfgPath).BuildSessionFactory();
            }


            
    public static ISession GetCurrentSession()
            
    {
                HttpContext context 
    = HttpContext.Current;
                ISession currentSession 
    = context.Items[CurrentSessionKey] as ISession;

                
    if (currentSession == null)
                
    {
                    currentSession 
    = sessionFactory.OpenSession();
                    context.Items[CurrentSessionKey] 
    = currentSession;
                }


                
    return currentSession;
            }


            
    public static void CloseSession()
            
    {
                HttpContext context 
    = HttpContext.Current;
                ISession currentSession 
    = context.Items[CurrentSessionKey] as ISession;

                
    if (currentSession == null)
                
    {
                    
    // No current session
                    return;
                }


                currentSession.Close();
                context.Items.Remove(CurrentSessionKey);
            }


            
    public static void CloseSessionFactory()
            
    {
                
    if (sessionFactory != null)
                
    {
                    sessionFactory.Close();
                }

            }

        }


    }


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

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

    从图中可以看出,第二次加载User对象,并没有从数据中获取数据,而是将没有设置Cache的Role信息从User里面获取。
    当然在利用缓存的时候,缓存不会知道另外一个进程存储的实体发生变化,应该自己建立一些策略来及时地更新缓存快照。而且当ISessionFactory销毁的时候,二级缓存也会随之销毁,这也是应用的时候,应该注意的。今天先写到这,有点困了。
  • 相关阅读:
    用户态和内核态
    04 _ 如何利用事务消息实现分布式事务?
    03 _ 消息模型:主题和队列有什么区别
    01 _ 为什么需要消息队列?
    洛谷P2257 YY的GCD
    HDU2669 Romantic (扩展欧几里德)
    CQOI2015 选数
    A. Pride
    测试开发进阶——python-java——appium003——Desired Capabilities —— 自动化常用方法——面试整理
    HDU 5050
  • 原文地址:https://www.cnblogs.com/jillzhang/p/697489.html
Copyright © 2011-2022 走看看