hibernate的session緩存機制

在我看來,任何框架的任何設計思路導出的機制都是一個目的:爲了簡化開發者的痛苦,乃至提高系統的執行效率。Hibernate的Session緩存就是這樣的一種機制。談論Session緩存之前,先看看Hibernate的Session是什麼。

Session 接口是 Hibernate 嚮應用程序提供的操縱數據庫的最主要的接口, 它提供了基本的保存, 更新, 刪除和加載 Java 對象的方法。Session會保留自己的一個緩存,這也是Hibernate的一級緩存。緩存中會存在一些持久化對象,這些對象是在完成CRUD操作的時候被保存的,所以它們都和數據庫中相關記錄對應。Session 緩存可減少 Hibernate 應用程序訪問數據庫的頻率。這樣可以提高效率,具體細節請往下看。

在 Session 接口的實現中包含一系列的 Java 集合, 這些 Java 集合構成了 Session 緩存. 只要 Session 實例沒有結束生命週期, 且沒有清理緩存,則存放在它緩存中的對象也不會結束生命週期。也就是說當先後執行兩個get方法來獲取數據庫的數據的時候,第一次獲取時Hibernate會自動生成一條select語句查找這項數據,然後保存在特定的持久化對象中,然後緊接着再次查詢同一條記錄(查詢條件相同)。這時,Hibernate會先進入Session緩存中查找,而不是直接進去數據庫。雖然這樣提高了效率,但如果數據在兩次查詢之間被更改,此Session還未死亡,那麼就永遠無法獲取最新的數據。不用擔心,Hibernate提供了三個操作Session緩存的方法:flush(),  reflesh(),  clear()。

 

我們依次來講解這三個方法,至於內部實現需要讀者自己去做Debug調試查看源碼:

1、flush()方法

flush:Session 按照緩存中對象的屬性變化來同步更新數據庫
默認情況下 Session 在以下時間點刷新緩存:
①顯式調用 Session 的 flush() 方法
②當應用程序調用 Transaction 的 commit()方法的時, 該方法先 flush ,然後在向數據庫提交事務
③當應用程序執行一些查詢(HQL, Criteria)操作時,如果緩存中持久化對象的屬性已經發生了變化,會先 flush 緩存,以保證查詢結果能夠反映持久化對象的最新狀態
flush 緩存的例外情況: 如果對象使用 native 生成器生成 OID, 那麼當調用 Session 的 save() 方法保存對象時, 會立即執行向數據庫插入該實體的 insert 語句.
commit() 和 flush() 方法的區別:flush 執行一系列 sql 語句,但不提交事務;commit 方法先調用flush() 方法,然後提交事務. 意味着提交事務意味着對數據庫操作永久保存下來。

2、reflesh()方法

使用此方法會強制發送select語句,以使Session緩存中的對象的狀態和數據表中的對應的記錄一致。但是在實際的測試中可能結果不盡人意,爲什麼呢?使用MySQL數據庫的朋友可能知道,MySQL支持可重複讀,也就是說讀過一次下次再讀還是那個數據,這是數據庫隔離級別的問題,此處不再詳細討論。更改隔離級別的方式有很多,我們着重講解Hibernate的配置方式,在cfg文件中增加如下配置即可(1,2,,4,8代表不同的隔離級別):

<property name="connection.isolation">2</property>

 

3、clear()方法

此方法用來清理緩存,直接將對象從Session緩存中刪除,在兩次查詢方法之間增加clear方法則可以保證都直接從數據庫獲取數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章