1. 程式人生 > >Session 中的快取機制

Session 中的快取機制

Session介面是Hibernate嚮應用程式提供的操縱資料庫的最主要的介面,它提供了基本的儲存、更新、刪除和查詢方法。Session具有一個快取,位於快取中的物件處於持久化狀態,它和資料庫中的相關記錄對應,Session能夠在某些時間點,按照快取中持久化物件的屬性變化來同步更新資料庫,這一過程被稱為清理快取。

處理持久化狀態,物件還能處於遊離狀態和臨時狀態,Session的特定方法能使物件從一個狀態轉換到另一個狀態。

一、Java物件在JVM中的生命週期

當應用程式通過new語句建立一個Java物件時,JVM會為這個物件分配一塊記憶體空間,只要這個物件被引用變數引用,它就一直存在於記憶體中。如果這個物件不被任何引用變數引用,它就結束生命週期,此時

JVM的垃圾回收器會在適當時候回收它佔用的記憶體。

二、理解Session的快取

如果希望一個Java物件一直處於生命週期中,就必須保證至少有一個變數引用它,或者在一個Java集合中存放了這個物件的引用。在Session介面的實現類SessionImpl中定義了一系列的Java集合,這些Java集合構成了Session的快取。

Session快取的三大作用:

1、減少訪問資料庫的頻率。從而提高資料訪問的效能。

2、保證快取中的物件與資料庫中的相關記錄保持同步。位於快取中的物件被稱為持久化物件。當快取中的物件的狀態發生了變換,Session並不會立即執行相應的SQL於戶,這使得Session

能把幾條相關的SQL語句合併為一條SQL語句,一邊減少訪問資料庫的次數,從而提高應用程式的效能。

3、當快取中的持久化物件之間存在迴圈關聯關係時,Session會保證不出現訪問物件圖的死迴圈,以及由於死迴圈引起的JVM棧溢位異常。

:當Session載入了物件後,會為物件的值型別的屬性賦值一份快照。當Session清理快取時,通過比較物件的當前屬性和它的快照,Session能夠判斷物件的哪些屬性發生了變化。

Session在清理快取時,按照以下順序執行SQL語句。

l按照應用程式呼叫session.save()方法的先後順序,執行所有對實體進行插入的insert語句。

l執行所有對實體進行更新的

update語句。

l執行所有對集合進行刪除的delete語句。

l執行所有對集合元素進行刪除、更新或者插入的SQL語句。

l執行所有對集合進行插入的insert語句。

l按照應用程式呼叫session.delete()方法的先後順序,執行所有對實體進行刪除的delete語句。

在預設情況下,Session會在下面的時間點清理快取。

l當應用程式呼叫net.sf.hibernate.Transactioncommit()方法的時候,commit()方法先清理快取,然後在向資料庫提交事務。

l當應用程式呼叫Sessionfind()或者iterate()時,如果快取中持久化物件的屬性發生了變化,就會先清理快取,以保證查詢結果能能反映持久化物件的最新狀態。

l當應用程式顯式呼叫Sessionflush()方法的時候。

Session進行清理快取的例外情況是,如果物件使用native生成OID,那麼當呼叫Sessionsave()儲存該物件時,會立即執行向資料庫插入實體的 insert語句

注:Sessioncommit()flush()方法的區別。flush方法進行清理快取的操作,執行一系列的SQL語句,但不會提交事務;commit方法會先呼叫flush方法,然後提交事務。提交事務意味著對資料庫所作的更新被永久儲存下來。

SessionsetFlushMode()方法用於設定清理快取的時間點。

清理快取的模式

Session的查詢方法

Sessioncommit()

Sessionflush()

FlushMode.AUTO

清理

清理

清理

FlushMode.COMMIT

不清理

清理

清理

FlushMode.NEVER

不清理

不清理

清理

AUTO時預設值,這也是優先考慮的清理模式,他會保證在整個事務中,資料保持一致。如果事務僅包含查詢資料庫的操作,而不會修改資料庫的資料,也可以選COMMIT模式,這可以避免在執行Session查詢方法時先清理快取,以稍微提高應用程式的效能。

在多說情況下,應用程式不需要顯式呼叫Sessionflush方法,flush方法適用於以下場合。

A、插入、刪除或更新某個持久化物件會引發資料庫中的觸發器。

B、在應用程式中混合使用Hibernate APIJDBC API

C、JDBC驅動程式不健壯,導致Hibernate在自動清理快取的模式下無法正常工作。

三、在Hibernate應用中Java物件的狀態

對於需要持久化的Java物件,在它的生命週期中,可處於以下三個狀態之一。

l臨時狀態(transient):剛剛用new語句建立,還沒有被持久化,不處於Session的快取中。處於臨時狀態的Java物件被稱為臨時物件。

l持久化狀態(persistent):已經被持久化,加入到Session的快取中。處於持久化狀態的Java物件被稱為持久化物件。

l遊離狀態(detached):已經被持久化,但不在處於Session的快取中。處於遊離狀態的Java物件被稱為遊離物件。

注:持久化類與持久化物件是不同的概念。持久化類的例項可以處於臨時狀態、持久化狀態和遊離狀態,其中處於持久化狀態的例項被稱為持久化物件。

1、臨時物件的特徵

不處於Session的快取中(不被任何一個Session例項關聯)在資料庫中沒有對應的記錄

以下情況下,Java物件進入臨時狀態:

A、new語句剛剛建立物件;

B、Sessiondelete()方法能使一個持久化物件或遊離物件轉變為臨時物件。

2、持久化物件的特徵

位於一個Session例項的快取中;持久化物件和資料庫中的相應記錄對應;Session在清理快取時,會根據持久化物件的屬性變化,來同步更新資料庫。

Session的許多方法能觸發Java物件轉變為持久化物件:

A、save把臨時轉為持久化狀態;

B、loadget返回的物件總處於持久化狀態;

C、find返回的List集合中存放的都是持久化物件;

D、updatesaveOrUpdatelock方法使遊離物件轉變為持久化物件;

E、當一個持久化物件關聯一個臨時物件,在允許級聯儲存的情況下,清理快取時會把臨時物件轉化為持久化物件。

3、遊離物件的特徵

不再位於Session的快取中;遊離物件是由持久化物件轉變過來的,因此再資料庫中可能存在與它對應的記錄(前提是沒有其他程式刪除這條記錄)。

Session的以下方法使持久化物件轉變為遊離物件:

A、close方法,快取被清理空,所有持久化物件都變為於哦裡物件;

B、evict方法能夠從快取中刪除一個持久化物件。

四、Session的儲存、更新、刪除和查詢方法

1Sessionsave方法

使一個臨時的物件轉變為持久化物件。

Sessionsave方法完成以下操作:

A、把物件加入到快取中,使它變為持久化物件。

B、選用對映檔案指定的識別符號生成器為持久化物件分配唯一的OID

C、計劃執行一個insert語句,把物件當前的屬性值組裝到insert語句中。

值得注意的是,save方法並不立即執行SQL insert語句。只有當Session清理快取時,才會執行語句。

Sessionsave方法是用來持久化一個臨時物件的。再應用中,不應該把持久化物件或遊離物件傳給save方法。

2Sessionupdate方法

使一個遊離物件轉變為持久化物件。

Sessionupdate方法完成以下操作:

A、把物件重新加入到Session的快取中,使它變為持久化物件。

B、計劃執行一個update語句。(不立即執行,清楚快取執行)

3SessionsaveOrUpdate方法

同時包含saveupdate方法的功能,如果傳入的引數是臨時物件,就呼叫save方法;如果傳入的引數是遊離物件,就呼叫update方法;如果傳入的引數是持久化物件,那就直接返回

4Sessionloadget方法

根據給定的OID從資料庫中載入一個持久化物件,這兩個方法的區別在於:當資料庫中不存在與OID對應的記錄時,load方法丟擲異常,而get方法返回null

5Sessiondelete方法

在資料庫中刪除與Java物件對應的記錄。如果傳入的引數時持久化物件,Session就計劃執行一個delete語句。如果傳入的引數時遊離物件,先是的遊離物件被Session關聯,使它變為持久化物件,然活計劃執行一個delete語句。