歡迎您光臨本站 註冊首頁

Hibernate中的Cache管理

←手機掃碼閱讀     火星人 @ 2014-03-10 , reply:0

Hibernate實現了良好的Cache機制,可以藉助Hibernate內部的Cache迅速提高系統的數據讀取性能.Hibernate中的Cache可分為兩層:一級Cache和二級Cache.

一級Cache:

Session實現了第一級Hibernate Cache,它屬於事務級數據緩衝.一旦事務結束,這個Cache也隨之失效.一個Session的生命周期對應一個資料庫事務或一個程序事務.

Session-cache保證了一個Session中兩次請求同一個對象時,取得的對象是同一個JAVA實例,有時它可以避免不必要的數據衝突.另外,它還能為另一些重要的性能提供保證:

1:在對一個對象進行自我循環引用時, 不至於產生堆棧溢出.

2:當資料庫事務結束時,對於同一個資料庫行,不會產生數據衝突,因為對於資料庫中的一行,最多只有一個對象來表示它.

3:一個事務中可能會有很多個處理單元,在每一個處理單元中做的操作都會立即被另外的處理單元得知.

我們不用刻意去打開Session-cache,它總是被打開並且不能被關閉.當使用save(),update()或saveOrUpdate()來保存數據更改,或通過load(),find(),list()等方法來得到對象時,對象就會被加入到Session-cache.

如果要同步很多數據對象,就需要有效地管理Cache,可以用Session的evict()方法從一級Cache中移除對象.如下:

Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
for(int i = 0 ; i <100000 ; i )
{
Student stu = new Student();

session.save(stu);
}
tx.commit();

session.close();在保存50000個或更多對象時,程序可能會拋出OutOfMemoryException異常,因為Hibernate Cache在一級緩存了新加入的所有對象.內存溢出.要解決這全問題就需要把JDBC批處理數量設置為一個合理的數值(一般是10~20).在Hibernate Cache的配置文件中可以加入以下屬性

<property name="hibernate.jdbc.batch_size"> 20 </property>

然後我們在程序中一定時刻就提交並更新Session的Hibernate Cache:

Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
for(int i = 0 ; i <100000 ; i )
{


Student stu = new Student();

session.save(stu);
if(i == 0) //每保存完20個對象后,進行如下操作
{
session.flush();//這個會提交更新
session.clear();//清除Cache,釋放內存
}
}

二級Cache

二級Cache是SessionFactory範圍內的緩存,所有的Session共享同一個二級Cache.在二級Cache中保存持久性實例的散裝形式的數據.二級Cache的內部如何實現並不重要,重要的是採用哪種正確的緩存策略,以及採用哪個Cache提供器.持久化不同的數據需要不同的Cache策略,比如一些因素將影響到Cache策略的選擇:數據的讀/寫比例,數據表是否能被其他的應用程序揚訪問等.對於一些讀/寫比例高的數據可以打開它的緩存,允許這些數據進入二級緩存容器有利於系統性能的優化;而對於能被其它應用程序訪問的數據對象,最好將此對象的二級Cache選項關閉.

設置Hibernate Cache的二級需要分兩步進行:確認使用什麼數據併發策略,然後配置緩存過期時間並設置Hibernate Cache提供器.

有4種內置的Hibernate數據併發衝突策略,代表資料庫隔離級別,如下:

1:事務(Transaction)僅在受管理的環境中可用.它保證可重讀的事務隔離級別,可以對讀/寫比例高,很少更新的數據採用該策略.

2:讀寫(read-write)使用時間戳機制維護讀寫提交事務隔離級別.可以對讀/寫比例高,很少更新的數據採用該策略.

3:非嚴格讀寫(notstrict-read-write)不保證Cache和資料庫之間的資料庫的一致性.使用此策略時,應該設置足夠的緩存過期時間,否則可能從緩存中讀出臟數據.當一些數據極少改變,並且當這些數據和資料庫有一部份不量影響不大時,可以使用此策略.

4:只讀(read-only)當確保數據永不改變時,可以使用此策略.

我們確定了Hibernate Cache策略后,就要挑選一個高效的Cache提供器,它將作為插件被Hibernate調用.Hibernate允許使用下述幾種緩存插件:EhCache:可以在JVM中作為一個簡單進程範圍內的緩存,它可以把緩存的數據放入內存或磁碟,並支持Hibernate中可選用的查詢緩存.

OpenSymphony OSCache:和EhCache相似,並且提供了豐富的緩存過期策略.

◆SwarmCache:可作為集群範圍的緩存,但不支持查詢緩存.

◆JBossCache:可作為集群範圍的緩衝,但不支持查詢緩存.

在Hibernate中使用EhCache

EhCache是一個純JAVA程序,可以在Hibernate中作為一個插件引入.在Hibernate中使用EhCache需要在Hibernate的配置文件中設置如下:

<propery name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<ehcache>
<diskStore path="c:\cache"/> //設置cache.data文件存放位置

<defaultCache
maxElementsInMemory="10000" //緩存中允許創建的最大對象數
eternal="false" //緩存中對象是否為永久的
timeToIdleSeconds="120"//緩存數據鈍化時間(即對象在它過期前的空閑時間)
timeToLiveSeconds="120"//緩存數據生存時間(即對象在它過期前的生存時間)
overflowToDisk="true"
/>

<cache name="Student" //用戶自定義的Cache配置
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/>
</ehcache>

此外我們還需要在持久化類的映射文件中進行配置.例如,Group(班級)和Student(學生)是一對多的關係,它們對應的數據表分別是t_group和t_student.現在要把Student類的數據進行二級緩存,這需要在二個映射文件中都對二級緩存進行配置.

在Group.hbm.xml中如下,在其<set></set>中添加

<cache usage="read-write"/><!——集合中的數據被緩存——>上述文件雖然在<set>標記中設置了<cache usage="read-write"/>,但Hibernate只是把Group相關的Student的主鍵ID加入到緩存中,如果希望把整個Student的散裝屬性都加入到二級緩存中,還需要在Student.hbm.xml文件的<class>標記中添加<cache>子標記.如下:

<class name="Student" table="t_student">
<cache usage="read-write" /><!--cache標記需跟在class標記后-->
</class>


[火星人 ] Hibernate中的Cache管理已經有1153次圍觀

http://coctec.com/docs/java/show-post-61446.html