標籤:一個資料庫 內容 持久化對象 結果 影響 應用程式 包括 .net ati
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緩衝