eric-1001c

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

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

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

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

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



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

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

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

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


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

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



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

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

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

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

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

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

          句. Session只有在清理緩存的時候才會執(zhí)行delete語句.
              該方法也能刪除多個對象, 但不推薦,效率低.如 session.delete("from Customer as c where c.id>8");
          posted on 2008-02-19 17:34 Eric-1001c 閱讀(409) 評論(0)  編輯  收藏 所屬分類: Hibernate
          主站蜘蛛池模板: 婺源县| 弥渡县| 中西区| 吴川市| 龙川县| 太湖县| 浠水县| 奉新县| 新源县| 应用必备| 云梦县| 彭阳县| 阿坝| 沅江市| 兰溪市| 盖州市| 巴马| 会理县| 武陟县| 萨迦县| 石台县| 呼和浩特市| 南康市| 清镇市| 都江堰市| 潼关县| 绥化市| 包头市| 广德县| 灵宝市| 惠东县| 东方市| 大渡口区| 泰宁县| 白朗县| 神农架林区| 宜良县| 延长县| 乐东| 石棉县| 江陵县|