標籤:c style blog java a http
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()
清理緩衝