国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Hibernate緩存何時使用和如何使用
Hibernate緩存何時使用和如何使用
2009-05-26 10:47
1. 關(guān)于hibernate緩存的問題:
1.1.1. 基本的緩存原理
Hibernate緩存分為二級,
第一級存放于session中稱為一級緩存,默認帶有且不能卸載。
第二級是由sessionFactory控制的進程級緩存。是全局共享的緩存,凡是會調(diào)用二級緩存的查詢方法 都會從中受益。只有經(jīng)正確的配置后二級緩存才會發(fā)揮作用。同時在進行條件查詢時必須使用相應(yīng)的方法才能從緩存中獲取數(shù)據(jù)。比如Query.iterate()方法、load、get方法等。必須注意的是session.find方法永遠是從數(shù)據(jù)庫中獲取數(shù)據(jù),不會從二級緩存中獲取數(shù)據(jù),即便其中有其所需要的數(shù)據(jù)也是如此。
查詢時使用緩存的實現(xiàn)過程為:首先查詢一級緩存中是否具有需要的數(shù)據(jù),如果沒有,查詢二級緩存,如果二級緩存中也沒有,此時再執(zhí)行查詢數(shù)據(jù)庫的工作。要注意的是:此3種方式的查詢速度是依次降低的。
1.2. 存在的問題
1.2.1. 一級緩存的問題以及使用二級緩存的原因
     因為Session的生命期往往很短,存在于Session內(nèi)部的第一級最快緩存的生命期當(dāng)然也很短,所以第一級緩存的命中率是很低的。其對系統(tǒng)性能的改善也是很有限的。當(dāng)然,這個Session內(nèi)部緩存的主要作用是保持Session內(nèi)部數(shù)據(jù)狀態(tài)同步。并非是hibernate為了大幅提高系統(tǒng)性能所提供的。
為了提高使用hibernate的性能,除了常規(guī)的一些需要注意的方法比如:
使用延遲加載、迫切外連接、查詢過濾等以外,還需要配置hibernate的二級緩存。其對系統(tǒng)整體性能的改善往往具有立竿見影的效果!
(經(jīng)過自己以前作項目的經(jīng)驗,一般會有3~4倍的性能提高)
1.2.2. N+1次查詢的問題
執(zhí)行條件查詢時,iterate()方法具有著名的 “n+1”次查詢的問題,也就是說在第一次查詢時iterate方法會執(zhí)行滿足條件的查詢結(jié)果數(shù)再加一次(n+1)的查詢。但是此問題只存在于第一次查詢時,在后面執(zhí)行相同查詢時性能會得到極大的改善。此方法適合于查詢數(shù)據(jù)量較大的業(yè)務(wù)數(shù)據(jù)。
但是注意:當(dāng)數(shù)據(jù)量特別大時(比如流水線數(shù)據(jù)等)需要針對此持久化對象配置其具體的緩存策略,比如設(shè)置其存在于緩存中的最大記錄數(shù)、緩存存在的時間等參數(shù),以避免系統(tǒng)將大量的數(shù)據(jù)同時裝載入內(nèi)存中引起內(nèi)存資源的迅速耗盡,反而降低系統(tǒng)的性能!?。?/div>
1.3. 使用hibernate二級緩存的其他注意事項:
1.3.1. 關(guān)于數(shù)據(jù)的有效性
另外,hibernate會自行維護二級緩存中的數(shù)據(jù),以保證緩存中的數(shù)據(jù)和數(shù)據(jù)庫中的真實數(shù)據(jù)的一致性!無論何時,當(dāng)你調(diào)用save()、update()或 saveOrUpdate()方法傳遞一個對象時,或使用load()、 get()、list()、iterate() 或scroll()方法獲得一個對象時, 該對象都將被加入到Session的內(nèi)部緩存中。 當(dāng)隨后flush()方法被調(diào)用時,對象的狀態(tài)會和數(shù)據(jù)庫取得同步。
也就是說刪除、更新、增加數(shù)據(jù)的時候,同時更新緩存。當(dāng)然這也包括二級緩存!
只要是調(diào)用hibernate API執(zhí)行數(shù)據(jù)庫相關(guān)的工作。hibernate都會為你自動保證 緩存數(shù)據(jù)的有效性?。?/div>
但是,如果你使用了JDBC繞過hibernate直接執(zhí)行對數(shù)據(jù)庫的操作。此時,Hibernate不會/也不可能自行感知到數(shù)據(jù)庫被進行的變化改動,也就不能再保證緩存中數(shù)據(jù)的有效性?。?/div>
這也是所有的ORM產(chǎn)品共同具有的問題。幸運的是,Hibernate為我們暴露了Cache的清除方法,這給我們提供了一個手動保證數(shù)據(jù)有效性的機會??!
一級緩存,二級緩存都有相應(yīng)的清除方法。
其中二級緩存提供的清除方法為:
按對象class清空緩存
按對象class和對象的主鍵id清空緩存
清空對象的集合中的緩存數(shù)據(jù)等。
1.3.2. 適合使用的情況
并非所有的情況都適合于使用二級緩存,需要根據(jù)具體情況來決定。同時可以針對某一個持久化對象配置其具體的緩存策略。
適合于使用二級緩存的情況:
1、數(shù)據(jù)不會被第三方修改;
一般情況下,會被hibernate以外修改的數(shù)據(jù)最好不要配置二級緩存,以免引起不一致的數(shù)據(jù)。但是如果此數(shù)據(jù)因為性能的原因需要被緩存,同時又有可能被第3方比如SQL修改,也可以為其配置二級緩存。只是此時需要在sql執(zhí)行修改后手動調(diào)用cache的清除方法。以保證數(shù)據(jù)的一致性
2、數(shù)據(jù)大小在可接收范圍之內(nèi);
如果數(shù)據(jù)表數(shù)據(jù)量特別巨大,此時不適合于二級緩存。原因是緩存的數(shù)據(jù)量過大可能會引起內(nèi)存資源緊張,反而降低性能。
   如果數(shù)據(jù)表數(shù)據(jù)量特別巨大,但是經(jīng)常使用的往往只是較新的那部分數(shù)據(jù)。此時,也可為其配置二級緩存。但是必須單獨配置其持久化類的緩存策略,比如最大緩存數(shù)、緩存過期時間等,將這些參數(shù)降低至一個合理的范圍(太高會引起內(nèi)存資源緊張,太低了緩存的意義不大)。
3、數(shù)據(jù)更新頻率低;
對于數(shù)據(jù)更新頻率過高的數(shù)據(jù),頻繁同步緩存中數(shù)據(jù)的代價可能和 查詢緩存中的數(shù)據(jù)從中獲得的好處相當(dāng),壞處益處相抵消。此時緩存的意義也不大。
4、非關(guān)鍵數(shù)據(jù)(不是財務(wù)數(shù)據(jù)等)
財務(wù)數(shù)據(jù)等是非常重要的數(shù)據(jù),絕對不允許出現(xiàn)或使用無效的數(shù)據(jù),所以此時為了安全起見最好不要使用二級緩存。
因為此時 “正確性”的重要性遠遠大于 “高性能”的重要性。
2. 目前系統(tǒng)中使用hibernate緩存的建議
1.4. 目前情況
一般系統(tǒng)中有三種情況會繞開hibernate執(zhí)行數(shù)據(jù)庫操作:
1、多個應(yīng)用系統(tǒng)同時訪問一個數(shù)據(jù)庫
   此種情況使用hibernate二級緩存會不可避免的造成數(shù)據(jù)不一致的問題,
   此時要進行詳細的設(shè)計。比如在設(shè)計上避免對同一數(shù)據(jù)表的同時的寫入操作,
   使用數(shù)據(jù)庫各種級別的鎖定機制等。
2、動態(tài)表相關(guān)
   所謂“動態(tài)表”是指在系統(tǒng)運行時根據(jù)用戶的操作系統(tǒng)自動建立的數(shù)據(jù)表。
   比如“自定義表單”等屬于用戶自定義擴展開發(fā)性質(zhì)的功能模塊,因為此時數(shù)據(jù)表是運行時建立的,所以不能進行hibernate的映射。因此對它的操作只能是繞開hibernate的直接數(shù)據(jù)庫JDBC操作。
如果此時動態(tài)表中的數(shù)據(jù)沒有設(shè)計緩存,就不存在數(shù)據(jù)不一致的問題。
   如果此時自行設(shè)計了緩存機制,則調(diào)用自己的緩存同步方法即可。
3、使用sql對hibernate持久化對象表進行批量刪除時
   此時執(zhí)行批量刪除后,緩存中會存在已被刪除的數(shù)據(jù)。
分析:
   當(dāng)執(zhí)行了第3條(sql批量刪除)后,后續(xù)的查詢只可能是以下三種方式:
a. session.find()方法:
根據(jù)前面的總結(jié),find方法不會查詢二級緩存的數(shù)據(jù),而是直接查詢數(shù)據(jù)庫。
所以不存在數(shù)據(jù)有效性的問題。
b. 調(diào)用iterate方法執(zhí)行條件查詢時:
根據(jù)iterate查詢方法的執(zhí)行方式,其每次都會到數(shù)據(jù)庫中查詢滿足條件的id值,然后再根據(jù)此id 到緩存中獲取數(shù)據(jù),當(dāng)緩存中沒有此id的數(shù)據(jù)才會執(zhí)行數(shù)據(jù)庫查詢;
如果此記錄已被sql直接刪除,則iterate在執(zhí)行id查詢時不會將此id查詢出來。所以,即便緩存中有此條記錄也不會被客戶獲得,也就不存在不一致的情況。(此情況經(jīng)過測試驗證)
c. 用get或load方法按id執(zhí)行查詢:
   客觀上此時會查詢得到已過期的數(shù)據(jù)。但是又因為系統(tǒng)中執(zhí)行sql批量刪除一般是
針對中間關(guān)聯(lián)數(shù)據(jù)表,對于中間關(guān)聯(lián)表的查詢一般都是采用條件查詢 ,按id來查詢某一條關(guān)聯(lián)關(guān)系的幾率很低,所以此問題也不存在!
   如果某個值對象確實需要按id查詢一條關(guān)聯(lián)關(guān)系,同時又因為數(shù)據(jù)量大使用 了sql執(zhí)行批量刪除。當(dāng)滿足此兩個條件時,為了保證按id 的查詢得到正確的結(jié)果,可以使用手動清楚二級緩存中此對象的數(shù)據(jù)的方法!!
(此種情況出現(xiàn)的可能性較小)
1.5.   建議
1、建議不要使用sql直接執(zhí)行數(shù)據(jù)持久化對象的數(shù)據(jù)的更新,但是可以執(zhí)行 批量刪除。(系統(tǒng)中需要批量更新的地方也較少)
2、如果必須使用sql執(zhí)行數(shù)據(jù)的更新,必須清空此對象的緩存數(shù)據(jù)。調(diào)用
SessionFactory.evict(class)
SessionFactory.evict(class,id)等方法。
3、在批量刪除數(shù)據(jù)量不大的時候可以直接采用hibernate的批量刪除,這樣就不存在繞開hibernate執(zhí)行sql產(chǎn)生的緩存數(shù)據(jù)一致性的問題。
4、不推薦采用hibernate的批量刪除方法來刪除大批量的記錄數(shù)據(jù)。
原因是hibernate的批量刪除會執(zhí)行1條查詢語句外加 滿足條件的n條刪除語句。而不是一次執(zhí)行一條條件刪除語句?。?/div>
當(dāng)待刪除的數(shù)據(jù)很多時會有很大的性能瓶頸?。?!如果批量刪除數(shù)據(jù)量較大,比如超過50條,可以采用JDBC直接刪除。這樣作的好處是只執(zhí)行一條sql刪除語句,性能會有很大的改善。同時,緩存數(shù)據(jù)同步的問題,可以采用 hibernate清除二級緩存中的相關(guān)數(shù)據(jù)的方法。
調(diào)用 SessionFactory.evict(class) ;SessionFactory.evict(class,id)等方法。
所以說,對于一般的應(yīng)用系統(tǒng)開發(fā)而言(不涉及到集群,分布式數(shù)據(jù)同步問題等),因為只在中間關(guān)聯(lián)表執(zhí)行批量刪除時調(diào)用了sql執(zhí)行,同時中間關(guān)聯(lián)表一般是執(zhí)行條件查詢不太可能執(zhí)行按id查詢。所以,此時可以直接執(zhí)行sql刪除,甚至不需要調(diào)用緩存的清除方法。這樣做不會導(dǎo)致以后配置了二級緩存引起數(shù)據(jù)有效性的問題。
退一步說,即使以后真的調(diào)用了按id查詢中間表對象的方法,也可以通過調(diào)用清除緩存的方法來解決。
4、具體的配置方法
根據(jù)我了解的很多hibernate的使用者在調(diào)用其相應(yīng)方法時都迷信的相信“hibernate會自行為我們處理性能的問題”,或者“hibernate 會自動為我們的所有操作調(diào)用緩存”,實際的情況是hibernate雖然為我們提供了很好的緩存機制和擴展緩存框架的支持,但是必須經(jīng)過正確的調(diào)用其才有可能發(fā)揮作用?。∷栽斐珊芏嗍褂胔ibernate的系統(tǒng)的性能問題,實際上并不是hibernate不行或者不好,而是因為使用者沒有正確的了解其使用方法造成的。相反,如果配置得當(dāng)hibernate的性能表現(xiàn)會讓你有相當(dāng)“驚喜的”發(fā)現(xiàn)。下面我講解具體的配置方法.
ibernate提供了二級緩存的接口:
net.sf.hibernate.cache.Provider,
同時提供了一個默認的 實現(xiàn)net.sf.hibernate.cache.HashtableCacheProvider,
也可以配置 其他的實現(xiàn) 比如ehcache,jbosscache等。
具體的配置位置位于hibernate.cfg.xml文件中
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.provider_class">net.sf.hibernate.cache.HashtableCacheProvider</property>
很多的hibernate使用者在 配置到 這一步 就以為 完事了,
注意:其實光這樣配,根本就沒有使用hibernate的二級緩存。同時因為他們在使用hibernate時大多時候是馬上關(guān)閉session,所以,一級緩存也沒有起到任何作用。結(jié)果就是沒有使用任何緩存,所有的hibernate操作都是直接操作的數(shù)據(jù)庫??!性能可以想見。
正確的辦法是除了以上的配置外還應(yīng)該配置每一個vo對象的具體緩存策略,在影射文件中配置。例如:
<hibernate-mapping>
<class name="com.sobey.sbm.model.entitySystem.vo.DataTypeVO" table="dcm_datatype">
<cache usage="read-write"/>
<id name="id" column="TYPEID" type="java.lang.Long">
<generator class="sequence"/>
</id>
<property name="name" column="NAME" type="java.lang.String"/>
<property name="dbType" column="DBTYPE" type="java.lang.String"/>
</class>
</hibernate-mapping>
關(guān)鍵就是這個<cache usage="read-write"/>,其有幾個選擇
read-only,read-write,transactional,等
然后在執(zhí)行查詢時 注意了 ,如果是條件查詢,或者返回所有結(jié)果的查詢,此時session.find()方法 不會獲取緩存中的數(shù)據(jù)。只有調(diào)用query.iterate()方法時才會調(diào)緩存的數(shù)據(jù)。
同時 get 和 load方法 是都會查詢緩存中的數(shù)據(jù) .
對于不同的緩存框架具體的配置方法會有不同,但是大體是以上的配置
(另外,對于支持事務(wù)型,以及支持集群的環(huán)境的配置我會爭取在后續(xù)的文章中中 發(fā)表出來)
3.總結(jié)
總之是根據(jù)不同的業(yè)務(wù)情況和項目情況對hibernate進行有效的配置和正確的使用,揚長避短。不存在適合于任何情況的一個“萬能”的方案。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Hibernate緩存
五、hibernate的Session操作, 查詢過濾, 緩存利用, 批量處理
Hibernate二級緩存攻略
HibernateDaoSupport的方法
談?wù)凥ibernate緩存使用(一)
Java面試題全集(2.1)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服