Hibernate緩存機(jī)制探討
緩存是提高硬件和應(yīng)用程序性能的一個關(guān)鍵因素,在對象映射框架中更是如此。因此,合理使用Hibernate緩存機(jī)制能夠大幅度的提高Hibernate應(yīng)用程序的性能。
Hibernate提供了兩級緩存架構(gòu),第一級緩存是Session的緩存,第二級緩存是一個用戶決定是否使用的緩存,能夠借助與第三方的組件實現(xiàn)。Hibernate則提供了緩存管理接口,應(yīng)用程序可以自由的對Hibernate緩存機(jī)制進(jìn)行管理。
緩存是對或計算代價較大的原始數(shù)據(jù)的復(fù)制存儲。通過在緩存(連續(xù)的內(nèi)存空間)存儲數(shù)據(jù),對緩存中的數(shù)據(jù)進(jìn)行訪問,可以縮短平均訪問時間,提高數(shù)據(jù)的平均傳輸速度。Hibernate緩存機(jī)制提供了這種高效傳輸?shù)氖侄巍?/P>
緩存首先出現(xiàn)在CPU中,由于CPU的速度很快,主存儲器的存儲速度無法與其相比,因而影響了計算機(jī)的執(zhí)行效率。在CPU和主存儲器之間加入了速度最快的SRAM作為CPU與相對低速的存儲器之間交換數(shù)據(jù)的緩沖區(qū),這樣可以大幅度提高系統(tǒng)的執(zhí)行效率,可且通過CACHE來事先讀取CPU可能需要的數(shù)據(jù)。推廣開來,凡是位于速度相差很大的兩種硬件或應(yīng)用之間的,用于協(xié)調(diào)兩者數(shù)據(jù)傳輸差異的結(jié)構(gòu)都可以稱為緩存。
緩存將最近訪問過的信息存儲在特殊內(nèi)存系統(tǒng)中以避免CPU在重新到主存儲器中存取。在特定的硬件基礎(chǔ)和應(yīng)用架構(gòu)之上,緩存往往是提升系統(tǒng)性能的關(guān)鍵因素之一。在使用數(shù)據(jù)庫的應(yīng)用系統(tǒng)中,緩存位于數(shù)據(jù)庫和應(yīng)用之間,在內(nèi)存中保存底層數(shù)據(jù)庫的數(shù)據(jù)副本(應(yīng)用程序經(jīng)常方位的數(shù)據(jù)),以便應(yīng)用程序之間重內(nèi)存中存取而不必頻繁的方位數(shù)據(jù)庫,因此提高了應(yīng)用程序訪問數(shù)據(jù)的效率。
緩存介于應(yīng)用程序的數(shù)據(jù)訪問層和數(shù)據(jù)庫等數(shù)據(jù)源層之間,一般位于內(nèi)存中,而數(shù)據(jù)庫等數(shù)據(jù)源長來自硬盤或網(wǎng)絡(luò)。相對于硬盤和網(wǎng)絡(luò),應(yīng)用程序訪問內(nèi)存的速度顯然要快的很多。不過如果緩存中數(shù)據(jù)量太大也可以放置到硬盤上,需要時在掉入內(nèi)存,這樣雖然速度慢些,但還是比直接從網(wǎng)絡(luò)獲取要快!
對于Hibernate而言,它是一個實現(xiàn)了對象關(guān)系映射的組件。應(yīng)用程序中的數(shù)據(jù)通過Hibernate緩存機(jī)制中的持久化實例反映。這些持久化實例維護(hù)的數(shù)據(jù)是來自于底層數(shù)據(jù)庫或即將同步更行到數(shù)據(jù)庫的數(shù)據(jù),為了獲取這些數(shù)據(jù),Hibernate必須頻繁的訪問數(shù)據(jù)庫,產(chǎn)生大量的數(shù)據(jù)庫連接操作和數(shù)據(jù)傳輸動作,效率較低。另外,Hibernate屏蔽了底層數(shù)據(jù)庫的操作細(xì)節(jié),讓用戶可以以操作對象的方式訪問關(guān)系數(shù)據(jù)庫中的數(shù)據(jù),在對象關(guān)系映射轉(zhuǎn)換的過程中,Hibernate勢必付出了一些系統(tǒng)開銷!
為了提升Hibernate的數(shù)據(jù)庫訪問效率并應(yīng)對Hibernate封裝底層數(shù)據(jù)庫的內(nèi)存開銷,需要引入緩存策略。緩存作為數(shù)據(jù)庫數(shù)據(jù)在內(nèi)存中的臨時容器,內(nèi)涵了數(shù)據(jù)庫數(shù)在內(nèi)存中的臨時副本。Hibernate讀取所需數(shù)據(jù)時,首先在緩存中查找(先是一級緩存再次是二級緩存),若果緩存中存在需要的數(shù)據(jù)則稱為命中(和CPU在一級緩存中取到需要的數(shù)據(jù)概念一樣),然后就會直接返回數(shù)據(jù),這樣的話就避免了數(shù)據(jù)庫調(diào)用的開銷,不過如果緩存中沒有所需要的數(shù)據(jù)還是會訪問底層數(shù)據(jù)庫。
Hibernate采用二級緩存體系,包括Session緩存(一級緩存)和SessionFactory緩存(二級緩存)。
(1)Session緩存是內(nèi)置的,默認(rèn)的,不能被卸載。Session維護(hù)了其自身生命周期中的一些持久化實例和它們的集合。(就像是一個方法中的變量)
(2)SessionFactory緩存即Hibernate二級緩存,按結(jié)構(gòu)可以分為內(nèi)置緩存和外置緩存兩種。
針對緩存的生命周期的不同,我們可以將Hibernate的緩存分為三個層次:
1.事物級緩存
緩存只能被當(dāng)前事物訪問。這個事物可以是一個數(shù)據(jù)庫事物(比如Session),也可以是某個應(yīng)用程序大的事物。緩存的聲明周期依賴于事物的生命周期,很顯然,就像是一個方法中的變量(內(nèi)部變量)方法執(zhí)行完后,其內(nèi)部變量就會小時除非我們在那個方法中將其存入一個全局變量的集合類中。因此,對于Session而言,事物級緩存有Session實現(xiàn)。Sessions內(nèi)部維護(hù)一個數(shù)據(jù)緩存這個緩存隨著Session的創(chuàng)建而建立,在Session關(guān)閉時將被JVM垃圾回收機(jī)制回收除非其還存在引用(即使把其放進(jìn)一個全局變量中例如集合)。在Hibernate緩存機(jī)制中,Session內(nèi)部緩存(說白了也就是Session內(nèi)部變量)只能在Session實例范圍中使用。
2.應(yīng)用級緩存
緩存在某個應(yīng)用范圍被所有事務(wù)共享(指的是數(shù)據(jù)庫事務(wù)Session)。緩存的聲明周期依賴于應(yīng)用程序的生命周期,當(dāng)這個應(yīng)用程序的生命周期結(jié)束時,緩存生命周球隨之結(jié)束(我們不妨理解為全局變量)。不過這里就存在一個問題,由于緩存被所有事務(wù)共享,緩存可能被這些事務(wù)并發(fā)訪問,這個主要必須依靠對緩存設(shè)置必要的事務(wù)隔離機(jī)制和緩存共享策略來盡力避免。另外,應(yīng)用級緩存在整個應(yīng)用范圍內(nèi)使用,數(shù)據(jù)量較大時可以存儲在硬盤上。
對于Hibernate而言,應(yīng)用級別緩存有SessionFactory實現(xiàn)。Session實例有SessionFactory創(chuàng)建,并共享SessionFactory的緩存。
其實我們可以這樣理解Hibernate緩存機(jī)制中的SessionFactory與Session,以及一級緩存和二級緩存。SessionFactory是一個可執(zhí)行類的話,二級緩存就相當(dāng)于其內(nèi)部的一個集合類作為其全局變量,而Session則可以看做其內(nèi)部的一個方法(或者是內(nèi)部方法中的內(nèi)部類的實例),類的方法肯定是可以訪問其類的變量(更何況全局變量),但是類的方法以結(jié)束其內(nèi)部類就會立即消失而類的全局變量則依然存在知道這個類執(zhí)行完所有方法。因此,如果我們想保存數(shù)據(jù)庫數(shù)據(jù)副本到二級緩存中,只能在這個類運行內(nèi)部方法時把帶到的數(shù)據(jù)存到全局變量(比如集合類中)中。
【編輯推薦】