eric-1001c

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            3 隨筆 :: 45 文章 :: 12 評(píng)論 :: 0 Trackbacks
          Session緩存其實(shí)就是一塊內(nèi)存空間,在這個(gè)內(nèi)存空間中存放了互相關(guān)聯(lián)的Java對(duì)象,Session負(fù)責(zé)根據(jù)持久化對(duì)象的狀態(tài)變化來(lái)同步更新數(shù)據(jù)庫(kù).Session的緩存是內(nèi)置的,不能被卸載,也被稱為Hibernate的第一級(jí)緩存,此外SessionFactory有一個(gè)內(nèi)置的緩存和一個(gè)外置的緩存,其中外置的緩存是可插拔的緩存插件,也被稱為Hibernate的第二級(jí)緩存,在默認(rèn)情況下,SessionFactory不會(huì)啟動(dòng)這個(gè)緩存插件.

          緩存的范圍和緩存的并發(fā)訪問(wèn)策略
          1.持久層的緩存范圍
              事務(wù)范圍:    緩存只能被當(dāng)前事務(wù)訪問(wèn),緩存的生命周期依賴于事務(wù)的生命周期.每個(gè)事務(wù)都有獨(dú)自的緩存
              進(jìn)程范圍:  緩存被進(jìn)程內(nèi)的所有事務(wù)共享,緩存的生命周期依賴于進(jìn)程的生命周期. 因?yàn)檫M(jìn)程的事務(wù)有可能并發(fā)訪問(wèn)緩存,所以必須對(duì)緩存采取必要的事務(wù)隔離機(jī)制;
              群集范圍: 在群集環(huán)境中, 緩存被同一個(gè)機(jī)器或多個(gè)機(jī)器上的多個(gè)進(jìn)程共享. 緩存中的數(shù)據(jù)被復(fù)制到集群環(huán)境中的每個(gè)進(jìn)程節(jié)點(diǎn),進(jìn)程之間通過(guò)遠(yuǎn)程通信來(lái)保證緩存中數(shù)據(jù)的一致性,

          緩存中的數(shù)據(jù)通常采用對(duì)象的散裝數(shù)據(jù)形式;
          2.緩存并發(fā)訪問(wèn)策略
              由上可見(jiàn), 進(jìn)程范圍或群集范圍緩存,即第二級(jí)緩存,會(huì)出現(xiàn)并發(fā)問(wèn)題.對(duì)第二級(jí)緩存可以設(shè)定以下四種類型的并發(fā)訪問(wèn)策略,每一個(gè)策略對(duì)應(yīng)一種事務(wù)隔離級(jí)別.
              1) 事務(wù)型:    僅僅在受管理環(huán)境中適用,對(duì)于經(jīng)常被讀但是很少被修改的數(shù)據(jù),可以防止臟讀和不可重復(fù)讀的并發(fā)問(wèn)題;
              2)讀寫(xiě)型:    僅僅在非群集的環(huán)境中適用,對(duì)于經(jīng)常被讀但是很少被修改的數(shù)據(jù),可以防止臟讀;
              3)非嚴(yán)格讀寫(xiě)型: 不保證緩存與數(shù)據(jù)庫(kù)中數(shù)據(jù)的一致性,對(duì)于極少被修改,并且允許偶爾臟讀的數(shù)據(jù),可以采用這種策略;
              4)只讀型: 對(duì)于從來(lái)不會(huì)被修改的數(shù)據(jù),如參考數(shù)據(jù),可以使用這個(gè)策略;

          只有符合以下條件的數(shù)據(jù)才適合于存放到第二級(jí)緩存中:
              1) 很少被修改的數(shù)據(jù);
              2) 不是很重要的數(shù)據(jù),允許出現(xiàn)偶爾的并發(fā)問(wèn)題;
              3)不會(huì)被并發(fā)訪問(wèn)的數(shù)據(jù);
              4)參考數(shù)據(jù);

          Hibernate的二級(jí)緩存SessionFactory是進(jìn)程范圍或群集范圍的緩存,因此需要采用適當(dāng)?shù)牟l(fā)訪問(wèn)策略,提供事務(wù)隔離級(jí)別,而且可以在每個(gè)類或每個(gè)集合的粒度上配置第二級(jí)緩存.緩存適配器(Cache Provider)用于把具體的緩存實(shí)現(xiàn)軟件于Hibernate集成.Hibernate還為查詢結(jié)果提供了一個(gè)查詢緩存,它依賴于第二級(jí)緩存.



          管理Hibernate的第一級(jí)緩存
              Session為應(yīng)用程序提供了兩個(gè)管理緩存方法evict(Object o)和clear()
                  evict(Object o) : 從緩存中清除參數(shù)指定的持久化對(duì)象;(適用于不希望session'按照該對(duì)象的狀態(tài)變化來(lái)同步更新數(shù)據(jù)庫(kù)和批量更新或批量刪除的場(chǎng)合)
                  clear(): 清空緩存中所有持久化對(duì)象
          *對(duì)于更好的批量更新或者批量刪除的場(chǎng)合應(yīng)該直接通過(guò)JDBC API訪問(wèn)數(shù)據(jù)庫(kù)的過(guò)程, 執(zhí)行SQL語(yǔ)句來(lái)減少Hibernate API的多次sql執(zhí)行, 或者調(diào)用相關(guān)的存儲(chǔ)過(guò)程. 這個(gè)時(shí)候還得注意

          Transaction接口來(lái)聲明事務(wù)邊界;

          管理Hibernate的第二級(jí)緩存
              由于第二級(jí)緩存是可配置的插件,Hibernate允許選用以下類型的緩存插件:
              1) EHCache: 進(jìn)程范圍內(nèi)的緩存, 對(duì)Hibernate的查詢緩存提供了支持;(net.sf.hibernate.cache.EhCacheProvider EHCache插件的適配器)
              2) OpenSymphony OSCache: 進(jìn)程范圍內(nèi)的緩存,提供了豐富的緩存數(shù)據(jù)過(guò)期策略,對(duì)Hibernate的查詢緩存提供了支持;(net.sf.hibernate.cache,OSCacheProvider OSCache插件

          的適配器);
              3) SwarmCache: 群集范圍的緩存,但不支持Hibernate的查詢緩存;(net.sf.hibernate.cache.SwarmCacheProvider SwarmCache插件的適配器)
              4) JBossCache: 群集范圍內(nèi)的緩存,支持事務(wù)并發(fā)訪問(wèn)策略,對(duì)Hibernate的查詢緩存提供了支持;(net.sf.hibernate,cache.TreeCacheProvider JBossCache插件的適配器)


          配置第二級(jí)緩存主要包含以下步驟:
              1) 在各個(gè)映射文件中為持久化類設(shè)置第二級(jí)緩存后者在Hibernate的配置文件hibernate.cfg.xml中集中設(shè)置第二級(jí)緩存,設(shè)置它的命名緩存的并發(fā)訪問(wèn)策略;
              2)選擇合適的緩存插件,手工編輯配置文件,為每個(gè)命名緩存設(shè)置數(shù)據(jù)過(guò)期策略;
                  <class name="mypack.Category" table="CATEGORIES">
                      <cache usage="read-write"/>
                      <id name="id" type="long" column="ID">
                  ...
                  </class>
          *如果只在category中配置cache,當(dāng)調(diào)用category.getItems().iterate()方法時(shí),Hibernate只會(huì)把items集合中的元素存放到緩存中,此時(shí)Hibernate僅僅把與Category關(guān)聯(lián)的Item對(duì)象的OID存放

          到緩存中.如果希望把整個(gè)Item對(duì)象散裝數(shù)據(jù)存入緩存,應(yīng)該在Item.hbm.xml文件中設(shè)置cache元素



          ***************************************************************************************************************************************************
          在默認(rèn)情況下,Session會(huì)在下面的時(shí)間點(diǎn)清理緩存.
              1) 當(dāng)應(yīng)用程序調(diào)用net.sf.hibernate.Transaction的commit()方法的時(shí)候,commit()方法先清理緩存, 然后再向數(shù)據(jù)庫(kù)提交事務(wù);
              2) 當(dāng)應(yīng)用程序調(diào)用Session的find()或者iterate()時(shí), 如果緩存中持久化對(duì)象的屬性發(fā)生了變化, 就會(huì)先清理緩存, 以保證查詢結(jié)果能反映持久化對(duì)象的最新?tīng)顟B(tài);
              3) 當(dāng)應(yīng)用程序顯式調(diào)用Session的flush()方法的時(shí)候;

          1. Session的save()方法
              save方法并不立即執(zhí)行SQL insert語(yǔ)句, 只有當(dāng)Session清理緩存的時(shí), 才會(huì)執(zhí)行SQL insert語(yǔ)句.如果在save()方法之后, 又修改了持久化對(duì)象的屬性, 這會(huì)使得Session在清理緩

          存時(shí), 額外執(zhí)行SQL update語(yǔ)句.
          2. Session的update()方法
              update方法會(huì)生成或調(diào)用一個(gè)計(jì)劃的update語(yǔ)句,并且Session只有在清理緩存的時(shí)候才會(huì)執(zhí)行update語(yǔ)句,在執(zhí)行時(shí)才會(huì)把Customer對(duì)象當(dāng)前的屬性值組裝到update語(yǔ)句中.
          **通過(guò)update()方法使游離對(duì)象被一個(gè)Session關(guān)聯(lián),即使沒(méi)有修改Customer對(duì)象的任何屬性,Session在清理緩存時(shí)也會(huì)執(zhí)行由update()方法計(jì)劃的update語(yǔ)句. 如果希望Session僅僅當(dāng)修

          改了Customer對(duì)象的屬性時(shí), 才執(zhí)行update語(yǔ)句, 可以把映射文件中<class>元素的select-before-update設(shè)為true, 該屬性的默認(rèn)值為false;
          **當(dāng)update()方法關(guān)聯(lián)一個(gè)游離對(duì)象時(shí), 如果在Session的緩存中已經(jīng)存在相同OID的持久化對(duì)象,會(huì)拋出異常.
          3. Session的saveOrUpdate()方法
              saveOrUpdate()方法同時(shí)包含了save()與update()方法的功能, 如果傳入的參數(shù)是臨時(shí)對(duì)象就調(diào)用save()方法; 如果傳入的參數(shù)是游離對(duì)象, 就調(diào)用update()方法; 如果傳入的參數(shù)

          是持久化對(duì)象, 那就直接返回.
          4. Session的load()和get()方法
              Session的load()和get()方法都能根據(jù)給定的OID從數(shù)據(jù)庫(kù)中加載一個(gè)持久化對(duì)象, 這兩個(gè)方法的區(qū)別在于: 當(dāng)數(shù)據(jù)庫(kù)中不存在與OID對(duì)應(yīng)的記錄時(shí), load()方法拋出

          net.sf.hibernate.ObjectNotFoundException異常,而get()返回null.
          5. Session的delete()方法
              如果傳入的參數(shù)是持久化對(duì)象, Session就計(jì)劃執(zhí)行一個(gè)delete語(yǔ)句. 如果傳入的參數(shù)是游離對(duì)象, 先使游離對(duì)象被Session關(guān)聯(lián), 使它變?yōu)槌志没瘜?duì)象, 然后計(jì)劃執(zhí)行一個(gè)delete語(yǔ)

          句. Session只有在清理緩存的時(shí)候才會(huì)執(zhí)行delete語(yǔ)句.
              該方法也能刪除多個(gè)對(duì)象, 但不推薦,效率低.如 session.delete("from Customer as c where c.id>8");
          posted on 2008-02-19 17:34 Eric-1001c 閱讀(407) 評(píng)論(0)  編輯  收藏 所屬分類: Hibernate
          主站蜘蛛池模板: 丹寨县| 合水县| 佛冈县| 西昌市| 宁乡县| 布尔津县| 于都县| 涪陵区| 德钦县| 宜兰市| 台州市| 鸡东县| 吴川市| 日照市| 海宁市| 西乌珠穆沁旗| 山丹县| 墨竹工卡县| 卢龙县| 通江县| 新沂市| 正定县| 海丰县| 闵行区| 潞西市| 新建县| 文山县| 抚远县| 泸水县| 辽中县| 商丘市| 安平县| 石门县| 保亭| 翼城县| 宁化县| 洞头县| 嘉鱼县| 仁化县| 樟树市| 鲁山县|