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目錄中有這樣兩個dllNHibernate.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語句看,第一次從數據庫中加在User數據
第二次
從圖中可以看出,第二次加載User對象,并沒有從數據中獲取數據,而是將沒有設置Cache的Role信息從User里面獲取。
當然在利用緩存的時候,緩存不會知道另外一個進程存儲的實體發生變化,應該自己建立一些策略來及時地更新緩存快照。而且當ISessionFactory銷毀的時候,二級緩存也會隨之銷毀,這也是應用的時候,應該注意的。今天先寫到這,有點困了。
出處:http://jillzhang.cnblogs.com/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。



浙公網安備 33010602011771號