Hibernate的緩存機(jī)制

          網(wǎng)上找到一些關(guān)于hibernate緩存的文章,個(gè)人覺得很不錯(cuò).整合了一下.
          http://www.javaresearch.org/article/53556.htm  Hibernate的緩存機(jī)制
          引用 :        緩存是介于應(yīng)用程序和物理數(shù)據(jù)源之間,其作用是為了降低應(yīng)用程序?qū)ξ锢頂?shù)據(jù)源訪問的頻次,從而提高了應(yīng)用的運(yùn)行性能。緩存內(nèi)的數(shù)據(jù)是對物理數(shù)據(jù)源中的數(shù)據(jù)的復(fù)制,應(yīng)用程序在運(yùn)行時(shí)從緩存讀寫數(shù)據(jù),在特定的時(shí)刻或事件會(huì)同步緩存和物理數(shù)據(jù)源的數(shù)據(jù)。
                  緩存的介質(zhì)一般是內(nèi)存,所以讀寫速度很快。但如果緩存中存放的數(shù)據(jù)量非常大時(shí),也會(huì)用硬盤作為緩存介質(zhì)。緩存的實(shí)現(xiàn)不僅僅要考慮存儲(chǔ)的介質(zhì),還要考慮到管理緩存的并發(fā)訪問和緩存數(shù)據(jù)的生命周期。

          Hibernate的緩存包括Session的緩存和SessionFactory的緩存,其中SessionFactory的緩存又可以分為兩類:內(nèi)置緩存和外置緩存。Session的緩存是內(nèi)置的,不能被卸載,也被稱為Hibernate的第一級緩存。SessionFactory的內(nèi)置緩存和 Session的緩存在實(shí)現(xiàn)方式上比較相似,前者是SessionFactory對象的一些集合屬性包含的數(shù)據(jù),后者是指Session的一些集合屬性包含的數(shù)據(jù)。SessionFactory的內(nèi)置緩存中存放了映射元數(shù)據(jù)和預(yù)定義SQL語句,映射元數(shù)據(jù)是映射文件中數(shù)據(jù)的拷貝,而預(yù)定義SQL語句是在 Hibernate初始化階段根據(jù)映射元數(shù)據(jù)推導(dǎo)出來,SessionFactory的內(nèi)置緩存是只讀的,應(yīng)用程序不能修改緩存中的映射元數(shù)據(jù)和預(yù)定義 SQL語句,因此SessionFactory不需要進(jìn)行內(nèi)置緩存與映射文件的同步。SessionFactory的外置緩存是一個(gè)可配置的插件。在默認(rèn)情況下,SessionFactory不會(huì)啟用這個(gè)插件。外置緩存的數(shù)據(jù)是數(shù)據(jù)庫數(shù)據(jù)的拷貝,外置緩存的介質(zhì)可以是內(nèi)存或者硬盤。 SessionFactory的外置緩存也被稱為Hibernate的第二級緩存。

          Hibernate的這兩級緩存都位于持久化層,存放的都是數(shù)據(jù)庫數(shù)據(jù)的拷貝,那么它們之間的區(qū)別是什么呢?為了理解二者的區(qū)別,需要深入理解持久化層的緩存的兩個(gè)特性:緩存的范圍和緩存的并發(fā)訪問策略。

          持久化層的緩存的范圍

          緩存的范圍決定了緩存的生命周期以及可以被誰訪問。緩存的范圍分為三類。

          1 事務(wù)范圍:緩存只能被當(dāng)前事務(wù)訪問。緩存的生命周期依賴于事務(wù)的生命周期,當(dāng)事務(wù)結(jié)束時(shí),緩存也就結(jié)束生命周期。在此范圍下,緩存的介質(zhì)是內(nèi)存。事務(wù)可以是數(shù)據(jù)庫事務(wù)或者應(yīng)用事務(wù),每個(gè)事務(wù)都有獨(dú)自的緩存,緩存內(nèi)的數(shù)據(jù)通常采用相互關(guān)聯(lián)的的對象形式。

          2 進(jìn)程范圍:緩存被進(jìn)程內(nèi)的所有事務(wù)共享。這些事務(wù)有可能是并發(fā)訪問緩存,因此必須對緩存采取必要的事務(wù)隔離機(jī)制。緩存的生命周期依賴于進(jìn)程的生命周期,進(jìn)程結(jié)束時(shí),緩存也就結(jié)束了生命周期。進(jìn)程范圍的緩存可能會(huì)存放大量的數(shù)據(jù),所以存放的介質(zhì)可以是內(nèi)存或硬盤。緩存內(nèi)的數(shù)據(jù)既可以是相互關(guān)聯(lián)的對象形式也可以是對象的松散數(shù)據(jù)形式。松散的對象數(shù)據(jù)形式有點(diǎn)類似于對象的序列化數(shù)據(jù),但是對象分解為松散的算法比對象序列化的算法要求更快。

          3 集群范圍:在集群環(huán)境中,緩存被一個(gè)機(jī)器或者多個(gè)機(jī)器的進(jìn)程共享。緩存中的數(shù)據(jù)被復(fù)制到集群環(huán)境中的每個(gè)進(jìn)程節(jié)點(diǎn),進(jìn)程間通過遠(yuǎn)程通信來保證緩存中的數(shù)據(jù)的一致性,緩存中的數(shù)據(jù)通常采用對象的松散數(shù)據(jù)形式。

          對大多數(shù)應(yīng)用來說,應(yīng)該慎重地考慮是否需要使用集群范圍的緩存,因?yàn)樵L問的速度不一定會(huì)比直接訪問數(shù)據(jù)庫數(shù)據(jù)的速度快多少。

          持久化層可以提供多種范圍的緩存。如果在事務(wù)范圍的緩存中沒有查到相應(yīng)的數(shù)據(jù),還可以到進(jìn)程范圍或集群范圍的緩存內(nèi)查詢,如果還是沒有查到,那么只有到數(shù)據(jù)庫中查詢。事務(wù)范圍的緩存是持久化層的第一級緩存,通常它是必需的;進(jìn)程范圍或集群范圍的緩存是持久化層的第二級緩存,通常是可選的。

          持久化層的緩存的并發(fā)訪問策略

          當(dāng)多個(gè)并發(fā)的事務(wù)同時(shí)訪問持久化層的緩存的相同數(shù)據(jù)時(shí),會(huì)引起并發(fā)問題,必須采用必要的事務(wù)隔離措施。

          在進(jìn)程范圍或集群范圍的緩存,即第二級緩存,會(huì)出現(xiàn)并發(fā)問題。因此可以設(shè)定以下四種類型的并發(fā)訪問策略,每一種策略對應(yīng)一種事務(wù)隔離級別。

          事務(wù)型:僅僅在受管理環(huán)境中適用。它提供了Repeatable Read事務(wù)隔離級別。對于經(jīng)常被讀但很少修改的數(shù)據(jù),可以采用這種隔離類型,因?yàn)樗梢苑乐古K讀和不可重復(fù)讀這類的并發(fā)問題。

          讀寫型:提供了Read Committed事務(wù)隔離級別。僅僅在非集群的環(huán)境中適用。對于經(jīng)常被讀但很少修改的數(shù)據(jù),可以采用這種隔離類型,因?yàn)樗梢苑乐古K讀這類的并發(fā)問題。

          非嚴(yán)格讀寫型:不保證緩存與數(shù)據(jù)庫中數(shù)據(jù)的一致性。如果存在兩個(gè)事務(wù)同時(shí)訪問緩存中相同數(shù)據(jù)的可能,必須為該數(shù)據(jù)配置一個(gè)很短的數(shù)據(jù)過期時(shí)間,從而盡量避免臟讀。對于極少被修改,并且允許偶爾臟讀的數(shù)據(jù),可以采用這種并發(fā)訪問策略。   只讀型:對于從來不會(huì)修改的數(shù)據(jù),如參考數(shù)據(jù),可以使用這種并發(fā)訪問策略。

          事務(wù)型并發(fā)訪問策略是事務(wù)隔離級別最高,只讀型的隔離級別最低。事務(wù)隔離級別越高,并發(fā)性能就越低。

          什么樣的數(shù)據(jù)適合存放到第二級緩存中?

          1、很少被修改的數(shù)據(jù) 

          2、不是很重要的數(shù)據(jù),允許出現(xiàn)偶爾并發(fā)的數(shù)據(jù)

          3、不會(huì)被并發(fā)訪問的數(shù)據(jù)

          4、參考數(shù)據(jù)

          不適合存放到第二級緩存的數(shù)據(jù)?

          1、經(jīng)常被修改的數(shù)據(jù)

          2、財(cái)務(wù)數(shù)據(jù),絕對不允許出現(xiàn)并發(fā)

          3、與其他應(yīng)用共享的數(shù)據(jù)。

          Hibernate的二級緩存

          如前所述,Hibernate提供了兩級緩存,第一級是Session的緩存。由于Session對象的生命周期通常對應(yīng)一個(gè)數(shù)據(jù)庫事務(wù)或者一個(gè)應(yīng)用事務(wù),因此它的緩存是事務(wù)范圍的緩存。第一級緩存是必需的,不允許而且事實(shí)上也無法比卸除。在第一級緩存中,持久化類的每個(gè)實(shí)例都具有唯一的OID。

          第二級緩存是一個(gè)可插拔的的緩存插件,它是由SessionFactory負(fù)責(zé)管理。由于SessionFactory對象的生命周期和應(yīng)用程序的整個(gè)過程對應(yīng),因此第二級緩存是進(jìn)程范圍或者集群范圍的緩存。這個(gè)緩存中存放的對象的松散數(shù)據(jù)。第二級對象有可能出現(xiàn)并發(fā)問題,因此需要采用適當(dāng)?shù)牟l(fā)訪問策略,該策略為被緩存的數(shù)據(jù)提供了事務(wù)隔離級別。緩存適配器用于把具體的緩存實(shí)現(xiàn)軟件與Hibernate集成。第二級緩存是可選的,可以在每個(gè)類或每個(gè)集合的粒度上配置第二級緩存。

          Hibernate的二級緩存策略的一般過程如下:

          1) 條件查詢的時(shí)候,總是發(fā)出一條select * from table_name where …. (選擇所有字段)這樣的SQL語句查詢數(shù)據(jù)庫,一次獲得所有的數(shù)據(jù)對象。 

          2) 把獲得的所有數(shù)據(jù)對象根據(jù)ID放入到第二級緩存中。 

          3) 當(dāng)Hibernate根據(jù)ID訪問數(shù)據(jù)對象的時(shí)候,首先從Session一級緩存中查;查不到,如果配置了二級緩存,那么從二級緩存中查;查不到,再查詢數(shù)據(jù)庫,把結(jié)果按照ID放入到緩存。 

          4) 刪除、更新、增加數(shù)據(jù)的時(shí)候,同時(shí)更新緩存。

          Hibernate的二級緩存策略,是針對于ID查詢的緩存策略,對于條件查詢則毫無作用。為此,Hibernate提供了針對條件查詢的Query緩存。

          Hibernate的Query緩存策略的過程如下: 

          1) Hibernate首先根據(jù)這些信息組成一個(gè)Query Key,Query Key包括條件查詢的請求一般信息:SQL, SQL需要的參數(shù),記錄范圍(起始位置rowStart,最大記錄個(gè)數(shù)maxRows),等。 

          2) Hibernate根據(jù)這個(gè)Query Key到Query緩存中查找對應(yīng)的結(jié)果列表。如果存在,那么返回這個(gè)結(jié)果列表;如果不存在,查詢數(shù)據(jù)庫,獲取結(jié)果列表,把整個(gè)結(jié)果列表根據(jù)Query Key放入到Query緩存中。 

          3) Query Key中的SQL涉及到一些表名,如果這些表的任何數(shù)據(jù)發(fā)生修改、刪除、增加等操作,這些相關(guān)的Query Key都要從緩存中清空

          http://www.javaeye.com/topic/249465 Hibernate緩存機(jī)制

          引用 :  Hibernate的緩存管理

            一級緩存的管理:

                evit(Object obj)  將指定的持久化對象從一級緩存中清除,釋放對象所占用的內(nèi)存資源,指定對象從持久化狀態(tài)變?yōu)槊摴軤顟B(tài),從而成為游離對象.
                clear()  將一級緩存中的所有持久化對象清除,釋放其占用的內(nèi)存資源
                contains(Object obj) 判斷指定的對象是否存在于一級緩存中.
                flush() 刷新一級緩存區(qū)的內(nèi)容,使之與數(shù)據(jù)庫數(shù)據(jù)保持同步.

            二級緩存的管理: 
             
                evict(Class arg0, Serializable arg1)  將某個(gè)類的指定ID的持久化對象從二級緩存中清除,釋放對象所占用的資源.

                Hibernate的二級緩存功能是靠配置二級緩存插件來實(shí)現(xiàn)的,Hibernate為了集成這些插件,Hibernate提供了org.hibernate.cache.CacheProvider借口,它充當(dāng)緩存插件與Hibernate之間的適配器 .

          常用的二級緩存插件
          EHCache  org.hibernate.cache.EhCacheProvider
          OSCache  org.hibernate.cache.OSCacheProvider
          SwarmCahe  org.hibernate.cache.SwarmCacheProvider
          JBossCache  org.hibernate.cache.TreeCacheProvider

          簡單介紹一下EHCache的配置
          hibernate.cfg.xml
          Xml代碼: <hibernate-configuration>
              <session-factory>
                 <!-- 設(shè)置二級緩存插件EHCache的Provider類-->
                 <property name="hibernate.cache.provider_class">
                    org.hibernate.cache.EhCacheProvider
                 </property>
                 <!-- 啟動(dòng)"查詢緩存" -->
                 <property name="hibernate.cache.use_query_cache">
                    true
                 </property>
              </session-factory>
            </hibernate-configuration>
          ehcache.xml
          Xml代碼:<ehcache>
            <!-- maxElementsInMemory為緩存對象的最大數(shù)目, eternal設(shè)置是否永遠(yuǎn)不過期,timeToIdleSeconds對象處于空閑狀態(tài)的最多秒數(shù),timeToLiveSeconds對象處于緩存狀態(tài)的最多秒數(shù) -->
            <diskStore path="java.io.tmpdir"/>
              <defaultCache maxElementsInMemory="10000" eternal="false"  timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true"/>
          </ehcache>
          ****.hbm.xml
          Xml代碼:

          <?xml version="1.0" encoding='UTF-8'?>
          <!DOCTYPE hibernate-mapping PUBLIC
                                      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                      "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

          <hibernate-mapping>
              
             <class>
                 <!-- 設(shè)置該持久化類的二級緩存并發(fā)訪問策略 read-only read-write nonstrict-read-write transactional-->
                 <cache usage="read-write"/>   
             </class>

          </hibernate-mapping>



          posted on 2009-11-18 14:12 AK47 閱讀(234) 評論(0)  編輯  收藏 所屬分類: Hibernate


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          <2009年11月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 平阳县| 菏泽市| 鲁山县| 石城县| 九龙县| 阳江市| 杭锦旗| 莱州市| 隆回县| 东兴市| 琼结县| 呈贡县| 巫山县| 浦北县| 山东省| 普兰县| 泸州市| 霞浦县| 额尔古纳市| 江安县| 琼海市| 建湖县| 奇台县| 峨眉山市| 莱芜市| 营口市| 南川市| 盘山县| 城口县| 和平区| 武冈市| 宜君县| 建昌县| 巩义市| 达州市| 丘北县| 白银市| 阿巴嘎旗| 双城市| 邳州市| 罗源县|