session快取(一級快取),sql查詢結果快取,由hibernate管理
sessionfactory內建快取,內建快取是hibernate自帶的,用於存放預定義的sql以及hbm.xml描述的元資料,不可解除安裝
sessionfactory外接快取(二級快取),由外部外掛程式提供,外接快取的資料是資料庫資料的拷貝,外接快取的介質可以是記憶體或者硬碟。
快取的範圍決定了快取的生命週期以及可以被誰訪問。快取的範圍分為三類。
1.事務範圍:快取只能被當前事務訪問。快取的生命週期依賴於事務的生命週期,當事務結束時,快取也就結束生命週期。在此範圍下,快取的介質是記憶體。事務可以是資料庫事務或者應用事務,每個事務都有獨自的快取,快取內的資料通常採用相互關聯的的物件形式。
2.程序範圍:快取被程序內的所有事務共享。這些事務有可能是併發訪問快取,因此必須對快取採取必要的事務隔離機制。快取的生命週期依賴於程序的生命週期,程序結束時,快取也就結束了生命週期。程序範圍的快取可能會存放大量的資料,所以存放的介質可以是記憶體或硬碟。快取內的資料既可以是相互關聯的物件形式也可以是物件的鬆散資料形式。鬆散的物件資料形式有點類似於物件的序列化資料,但是物件分解為鬆散的演算法比物件序列化的演算法要求更快。
3.集群範圍:在集群環境中,快取被乙個機器或者多個機器的程序共享。快取中的資料被複製到集群環境中的每個程序節點,程序間通過遠端通訊來保證快取中的資料的一致性,快取中的資料通常採用物件的鬆散資料形式。
當多個併發的事務同時訪問持久化層的快取的相同資料時,會引起併發問題,必須採用必要的事務隔離措施。在程序範圍或集群範圍的快取,即第二級快取,會出現併發問題。因此可以設定以下四種型別的併發訪問策略,每一種策略對應一種事務隔離級別。
1.事務型:僅僅在受管理環境中適用。它提供了repeatable read事務隔離級別。對於經常被讀但很少修改的資料,可以採用這種隔離型別,因為它可以防止髒讀和不可重複讀這類的併發問題。
2.讀寫型:提供了read committed事務隔離級別。僅僅在非集群的環境中適用。對於經常被讀但很少修改的資料,可以採用這種隔離型別,因為它可以防止髒讀這類的併發問題。
3.非嚴格讀寫型:不保證快取與資料庫中資料的一致性。如果存在兩個事務同時訪問快取中相同資料的可能,必須為該資料配置乙個很短的資料過期時間,從而盡量避免髒讀。對於極少被修改,並且允許偶爾髒讀的資料,可以採用這種併發訪問策略。
因此二級快取的適用場景:
1. 很少被修改的資料
2. 不是很重要的資料,允許出現偶爾併發的資料
3. 不會被併發訪問的資料
4. 參考資料
不適用場景:
不適合存放到第二級快取的資料?
1. 經常被修改的資料
2. 財務資料,絕對不允許出現併發
ehcache、opensymphony oscache:程序範圍快取
swarmcache、jbosscache:集群快取
ehcache為例:
類級別快取
集合級別快取(一定要配合類級別快取一起使用,否則它只是快取obj的oid,然後根據乙個個的oid去資料庫分別獲取,傳送的sql反而增多)
hql查詢需要啟用查詢快取,否則快取不會生效,setcacheable(true)
更新時間戳緩:記錄所有操作時間戳,通過比較時間戳得知快取資料是否過期而需要重新向資料庫查詢
query.list():查詢的sql返回包含表中所有字段
query.iterate(),一般使用list而非iterate:查詢的sql只包含id,然後再根據id去查需要字段(通過快取再到資料庫),適用場景:表包含大量欄位且二級快取有快取物件執行的查詢不同
1.list()方法在執行時,是直接執行查詢結果所需要的查詢語句,而iterator()方法則是先執行得到物件id的查詢,然後再根據每個id值去取得所要查詢的物件。因此,對於list()方式的查詢通常只會執行乙個sql語句,而對於iterator()方法的查詢則可能需要執行n+1條sql語句(n為結果集中的記錄數)。iterator()方法只是可能執行n+1條資料,具體執行sql語句的數量取決於快取的情況以及對結果集的訪問情況。
2.快取的使用,list()方法只能使用二級快取中的查詢快取,而無法使用二級快取對單個物件的快取(但是會把查詢出的物件放入二級快取中)。所以,除非重複執行相同的查詢操作,否則無法利用快取的機制來提高查詢的效率。iterator()方法則可以充分利用二級快取,在根據id檢索物件的時候會首先到快取中查詢,只有在找不到的情況下才會執行相應的查詢語句。所以,快取中物件的存在與否會影響到sql語句的執行數量。
3.對於結果集的處理方法不同,list()方法會一次獲得所有的結果集物件,而且它會依據查詢的結果初始化所有的結果集物件。這在結果集非常大的時候必然會佔據非常多的記憶體,甚至會造成記憶體溢位情況的發生。iterator()方法在執行時不會一次初始化所有的物件,而是根據對結果集的訪問情況來初始化物件。因此在訪問中可以控制快取中物件的數量,以避免占用過多快取,導致記憶體溢位情況的發生。使用iterator()方法的另外乙個好處是,如果只需要結果集中的部分記錄,那麼沒有被用到的結果物件根本不會被初始化。所以,對結果集的訪問情況也是呼叫iterator()方法時執行資料庫sql語句多少的乙個因素。
hibernate二級快取
cacheconcurrencystrategy.none cacheconcurrencystrategy.read only 唯讀模式,在此模式下,如果對資料進行更新操作,會有異常 cacheconcurrencystrategy.read write 讀寫模式在更新快取的時候會把快取裡面的資料...
Hibernate二級快取
hibernate的session在事務級別進行持久化資料的快取操作。當然,也有可能分別為每個類 或集合 配置集群 或jvm級別 sessionfactory級別 的快取。你甚至可以為之插入乙個集群的快取。注意,快取永遠不知道其他應用程式對持久化倉庫 資料庫 可能進行的修改 即使可以將快取資料設定為...
Hibernate二級快取
hibernate提供的快取 有一級快取 二級快取。目的是為了減少對資料庫的訪問次數,提公升程式執行效率!一級快取 基於session 的快取,快取內容只在當前 session 有效,session 關閉,快取內容失效!特點 作用範圍較小!快取的事件短。快取效果不明顯。二級快取 hibernate提...