1. 程式人生 > >hibernate session緩存

hibernate session緩存

最新 更新 數據庫連接 變量 rac 更新數據 article 插入 evel

Session 概述

Session 接口是 Hibernate 向應用程序提供的操縱數據庫的最基本的接口, 它提供了基本的保存, 更新, 刪除和載入 Java 對象的方法.

Session 具有一個緩存, 位於緩存中的對象稱為持久化對象, 它和數據庫中的相關記錄相應. Session 可以在某些時間點, 依照緩存中對象的變化來運行相關的 SQL 語句, 來同步更新數據庫, 這一過程被稱為刷新緩存(flush)

站在持久化的角度, Hibernate 把對象分為 4 種狀態: 持久化狀態, 暫時狀態, 遊離狀態, 刪除狀態. Session 的特定方法能使對象從一個狀態轉換到還有一個狀態.


Session 緩存

在 Session 接口的實現中包括一系列的 Java 集合, 這些 Java 集合構成了 Session 緩存. 僅僅要 Session 實例沒有結束生命周期, 且沒有清理緩存。則存放在它緩存中的對象也不會結束生命周期

Session 緩存可降低 Hibernate 應用程序訪問數據庫的頻率。

技術分享


操作 Session 緩存

技術分享


flush()

flush:使數據庫表中的記錄和session緩存中的對象的狀態保持一致。為了保持一致。則可能會發送相應的sql語句。

默認情況下 Session 在下面時間點刷新緩存:

顯式調用 Session 的 flush() 方法,可能會發送sql語句(為什麽使用可能,由於查詢得到數據庫中的狀態與當前對象狀態一致則不會發送sql更新),但不會提交事務(發送了sql語句。必須提交事務才會更新數據庫)

當應用程序調用 Transaction 的 commit()方法的時, 該方法先 flush(更新) ,然後在向數據庫提交事務

當應用程序運行一些查詢(HQL, Criteria)操作時,假設緩存中持久化對象的屬性已經發生了變化。會先 flush 緩存。以保證查詢結果可以反映持久化對象的最新狀態(當然這樣的情況也僅僅是在事務範圍內更新了,還未同步到數據庫。僅僅有提交事務才會更新到數據庫)

flush 緩存的例外情況: 假設對象使用 native 生成器生成 OID(記錄的id是由底層數據庫使用自增生成的), 那麽當調用 Session 的 save() 方法保存對象時, 會馬上運行向數據庫插入該實體的 insert 語句同步到數據庫.由於save方法後必須保證id是存在的。(假設id是由hibernate生成則才是在commit提交事務時才發送insert同步到數據庫)

commit() 和 flush() 方法的差別:flush 運行一系列 sql 語句,但不提交事務;commit 方法先調用flush() 方法,然後提交事務. 意味著提交事務意味著對數據庫操作永久保存下來。


設定刷新緩存的時間點(了解就可以。通常不會去更改)

若希望改變 flush 的默認時間點, 能夠通過 Session 的 setFlushMode() 方法顯式設定 flush 的時間點
技術分享


refresh()

會強制發送select語句,以使session緩存中對象的狀態和數據庫表中的相應的記錄保持一致。受數據庫隔離級別控制。

(必須了解數據庫隔離級別,例如以下所看到的)


數據庫的隔離級別

對於同一時候執行的多個事務, 當這些事務訪問數據庫中同樣的數據時, 假設沒有採取必要的隔離機制, 就會導致各種並發問題:

臟讀: 對於兩個事物 T1, T2, T1 讀取了已經被 T2 更新但還沒有被提交的字段. 之後, 若 T2 回滾, T1讀取的內容就是暫時且無效的.

不可反復讀: 對於兩個事物 T1, T2, T1 讀取了一個字段, 然後 T2 更新了該字段. 之後, T1再次讀取同一個字段, 值就不同了.

幻讀: 對於兩個事物 T1, T2, T1 從一個表中讀取了一個字段, 然後 T2 在該表中插入了一些新的行. 之後, 假設 T1 再次讀取同一個表, 就會多出幾行.

數據庫事務的隔離性: 數據庫系統必須具有隔離並發執行各個事務的能力, 使它們不會相互影響, 避免各種並發問題.

一個事務與其它事務隔離的程度稱為隔離級別. 數據庫規定了多種事務隔離級別, 不同隔離級別相應不同的幹擾程度, 隔離級別越高, 數據一致性就越好, 但並發性越弱

數據庫提供的 4 種事務隔離級別:

技術分享

Oracle 支持的 2 種事務隔離級別:READ COMMITED, SERIALIZABLE. Oracle 默認的事務隔離級別為: READ COMMITED

Mysql 支持 4 中事務隔離級別. Mysql 默認的事務隔離級別為: REPEATABLE READ

在 MySql 中設置隔離級別

  • 每啟動一個 mysql 程序, 就會獲得一個單獨的數據庫連接. 每一個數據庫連接都有一個全局變量 @@tx_isolation, 表示當前的事務隔離級別. MySQL 默認的隔離級別為 Repeatable Read
  • 查看當前的隔離級別: SELECT @@tx_isolation;
  • 設置當前 mySQL 連接的隔離級別:
    set transaction isolation level read committed;
  • 設置數據庫系統的全局的隔離級別:
    set global transaction isolation level read committed;

在 Hibernate 中設置隔離級別

  • JDBC數據庫連接使用數據庫系統默認的隔離級別.在Hibernate的配置文件裏能夠顯式的設置隔離級別.每個隔離級別都相應一個整數: –1.READ UNCOMMITED –2.READ COMMITED –4.REPEATABLE READ –8.SERIALIZEABLE
  • Hibernate通過為Hibernate映射文件指定hibernate.connection.isolation屬性來設置事務的隔離級別

clear()

清理緩存








hibernate session緩存