hibernate學習筆記:hibernate中的Cache管理

Hibernate 中實現了良好的Cache 機制,咱們能夠藉助Hibernate 內部的Cache迅速提升系統數據讀取性能。

須要注意的是:Hibernate作爲一個應用級的數據訪問層封裝,只能在其做用範圍內保持Cache中數據的的有效性,也就是說,在咱們的系統與第三方系統共享數據庫的狀況下,Hibernate的Cache機制可能失效。一個很簡單的例子,若是你用access修改了庫中的值,那麼這就不會更新JVM中的緩衝池,這就致使了贓數據的產生。

Hibernate 在本地JVM 中維護了一個緩衝池,並將從數據庫得到的數據保存到池中以供下次重複使用(若是在Hibernate中數據發生了變更,Hibernate一樣也會更新池中的數據版本)。此時,若是有第三方系統對數據庫進行了更改,那麼,Hibernate並不知道數據庫中的數據已經發生了變化,也就是說,池中的數據仍是修改以前的版本,下次讀取時,Hibernate會將此數據返回給上層代碼,從而致使潛在的問題。外部系統的定義,並不是限於本系統以外的第三方系統,即便在本系統中,若是出現了繞過Hibernate數據存儲機制的其餘數據存取手段,那麼Cache的有效性也必須細加考量。如,在同一套系統中,基於Hibernate和基於JDBC的兩種數據訪問方式並存,那麼經過JDBC更新數據庫的時候,Hibernate一樣沒法獲知數據更新的狀況,從而致使髒數據的出現。

基於Java 的Cache 實現,最簡單的莫過於HashTable,hibernate 提供了基於Hashtable 的Cache 實現機制,不過,因爲其性能和功能上的侷限,僅供開發調試中使用。同時,Hibernate 還提供了面向第三方Cache 實現的接口,如JCS、EHCache、OSCache、JBoss Cache、SwarmCache等。

Hibernate中的Cache大體分爲兩層,第一層Cache在Session實現,屬於事務級數據緩衝,一旦事務結束,這個Cache 也就失效。此層Cache 爲內置實現,無需咱們進行干涉。第二層Cache,是Hibernate 中對其實例範圍內的數據進行緩存的管理容器。

咱們主要學習第二層Cache。

Hibernate早期版本中採用了JCS(Java Caching System -Apache Turbine項目中的一個子項目)做爲默認的第二層Cache實現。因爲JCS的發展停頓,以及其內在的一些問題(在某些狀況下,可能致使內存泄漏以及死鎖),新版本的Hibernate已經將JCS去除,並用EHCache做爲其默認的第二級Cache實現。相對JCS,EHCache更加穩定,並具有更好的緩存調度性能,缺陷是目前還沒法作到分佈式緩存,若是咱們的系統須要在多臺設備上部署,並共享同一個數據庫,必須使用支持分佈式緩存的Cache實現(如JCS、JBossCache)以免出現不一樣系統實例之間緩存不一致而致使髒數據的狀況。Hibernate對Cache進行了良好封裝,透明化的Cache機制使得咱們在上層結構的實現中無需面對繁瑣的Cache維護細節。

目前Hibernate支持的Cache實現有:

HashTable:net.sf.hibernate.cache.HashtableCacheProvider 支持查詢緩衝。

EHCache:net.sf.ehcache.hibernate.Provider 支持查詢緩衝。

OSCache:net.sf.hibernate.cache.OSCacheProvider 支持查詢緩衝。

SwarmCache:net.sf.hibernate.cache.SwarmCacheProvider 支持集羣。

JBossCache:net.sf.hibernate.cache.TreeCacheProvider 支持集羣。

其中SwarmCache 提供的是invalidation 方式的分佈式緩存,即當集羣中的某個節點更新了緩存中的數據,即通知集羣中的其餘節點將此數據廢除,以後各個節點須要用到這個數據的時候,會從新從數據庫中讀入並填充到緩存中。而JBossCache提供的是Reapplication式的緩衝,即若是集羣中某個節點的數據發生改變,此節點會將發生改變的數據的最新版本複製到集羣中的每一個節點中以保持全部節點狀態一致。

使用第二層Cache,須要在hibernate的配置文件進行配置(省略)主要介紹一下cache策略

cache策略可選值有如下幾種:

1. read-only 只讀。
2. read-write 可讀可寫。
3. nonstrict-read-write 若是程序對併發數據修改要求不是很是嚴格,只是偶爾須要更新數據,能夠採用本選項,以減小無謂的檢查,得到較好的性能。
4. transactional 事務性cache。在事務性Cache 中,Cache 的相關操做也被添加到事務之中,若是因爲某種緣由致使事務失敗,咱們能夠連同緩衝池中的數據一同回滾到事務開始以前的狀態。目前Hibernate 內置的Cache 中,只有JBossCache 支持事務性的Cache實現。

其餘參數簡介:

maxElementsInMemory="10000" //Cache中最大容許保存的數據數量
eternal="false" //Cache中數據是否爲常量
timeToIdleSeconds="120" //緩存數據鈍化時間
timeToLiveSeconds="120" //緩存數據的生存時間
overflowToDisk="true" //內存不足時,是否啓用磁盤緩存


須要注意的是Hibernate 的數據庫查詢機制。咱們從查詢結果中取出數據的時候,用的最多的是兩個方法:Query.list();Query.iterate();

對於list方法而言,實際上Hibernate是經過一條Select SQL獲取全部的記錄。並將其讀出,填入到POJO中返回。

而iterate 方法,則是首先經過一條Select SQL 獲取全部符合查詢條件的記錄的id,再對這個id 集合進行循環操做,經過單獨的Select SQL 取出每一個id 所對應的記錄,以後填入POJO中返回。

也就是說,對於list 操做,須要一條SQL 完成。而對於iterate 操做,須要n+1條SQL。

看上去iterate方法彷佛有些多餘,但在不一樣的狀況下確依然有其獨特的功效,如對海量數據的查詢,若是用list方法將結果集一次取出,內存的開銷可能沒法承受。另外一方面,對於咱們如今的Cache機制而言,list方法將不會從Cache中讀取數據,它老是一次性從數據庫中直接讀出全部符合條件的記錄。而iterate 方法由於每次根據id獲取數據,這樣的實現機制也就爲從Cache讀取數據提供了可能,hibernate首先會根據這個id 在本地Cache 內尋找對應的數據,若是沒找到,再去數據庫中檢索。數據庫

 

資料:Hibernate 開發指南緩存

相關文章
相關標籤/搜索