參考代碼下載github:https://github.com/changwensir/java-ee/tree/master/hibernate4
Session 接口是 Hibernate 向利用程序提供的操縱數(shù)據(jù)庫的最主要的接口, 它提供了基本的保存, 更新, 刪除和加載 Java 對象的方法.
Session 具有1個緩存, 位于緩存中的對象稱為持久化對象, 它和數(shù)據(jù)庫中的相干記錄對應(yīng). Session 能夠在某些時間點, 依照緩存中對象的變化來履行相干的 SQL 語句, 來同步更新數(shù)據(jù)庫, 這1進程被稱為刷新緩存(flush)
站在持久化的角度, Hibernate 把對象分為 4 種狀態(tài): 持久化狀態(tài), 臨時狀態(tài), 游離狀態(tài), 刪除狀態(tài). Session 的特定方法能使對象從1個狀態(tài)轉(zhuǎn)換到另外一個狀態(tài)
測試用的init,before初始,結(jié)束方法請參考上篇文章http://blog.csdn.net/ochangwen/article/details/52575246
在 Session 接口的實現(xiàn)中包括1系列的 Java 集合, 這些 Java 集合構(gòu)成了 Session 緩存. 只要 Session 實例沒有結(jié)束生命周期, 且沒有清算緩存,則寄存在它緩存中的對象也不會結(jié)束生命周期
Session 緩存可減少 Hibernate 利用程序訪問數(shù)據(jù)庫的頻率。
flush:Session 依照緩存中對象的屬性變化來同步更新數(shù)據(jù)庫
默許情況下 Session 在以下時間點刷新緩存:
- 顯式調(diào)用 Session 的 flush() 方法
- 當(dāng)利用程序調(diào)用 Transaction 的 commit()方法的時, 該方法先 flush ,然后在向數(shù)據(jù)庫提交事務(wù)
- 當(dāng)利用程序履行1些查詢(HQL, Criteria)操作時,如果緩存中持久化對象的屬性已產(chǎn)生了變化,會先 flush 緩存,以保證查詢結(jié)果能夠反應(yīng)持久化對象的最新狀態(tài)
flush 緩存的例外情況: 如果對象使用 native 生成器生成 OID, 那末當(dāng)調(diào)用 Session 的 save() 方法保存對象時, 會立即履行向數(shù)據(jù)庫插入該實體的 insert 語句.
commit() 和 flush() 方法的區(qū)分:flush 履行1系列 sql 語句,但不提交事務(wù);commit 方法先調(diào)用flush() 方法,然后提交事務(wù). 意味著提交事務(wù)意味著對數(shù)據(jù)庫操作永久保存下來。
對同時運行的多個事務(wù), 當(dāng)這些事務(wù)訪問數(shù)據(jù)庫中相同的數(shù)據(jù)時, 如果沒有采取必要的隔離機制, 就會致使各種并提問題:
1).臟讀: 對兩個事物 T1, T2, T1 讀取了已被 T2 更新但還沒有被提交的字段. 以后, 若 T2 回滾, T1讀取的內(nèi)容就是臨時且無效的.
2).不可重復(fù)讀: 對兩個事物 T1, T2, T1 讀取了1個字段, 然后 T2 更新了該字段. 以后, T1再次讀取同1個字段, 值就不同了.
3).幻讀: 對兩個事物 T1, T2, T1 從1個表中讀取了1個字段, 然后 T2 在該表中插入了1些新的行. 以后, 如果 T1 再次讀取同1個表, 就會多出幾行.
數(shù)據(jù)庫事務(wù)的隔離性: 數(shù)據(jù)庫系統(tǒng)必須具有隔離并發(fā)運行各個事務(wù)的能力, 使它們不會相互影響, 避免各種并提問題.
1個事務(wù)與其他事務(wù)隔離的程度稱為隔離級別. 數(shù)據(jù)庫規(guī)定了多種事務(wù)隔離級別, 不同隔離級別對應(yīng)不同的干擾程度, 隔離級別越高, 數(shù)據(jù)1致性就越好, 但并發(fā)性越弱
Oracle 支持的 2 種事務(wù)隔離級別:READ COMMITED, SERIALIZABLE. Oracle 默許的事務(wù)隔離級別為: READ COMMITED
Mysql 支持 4 中事務(wù)隔離級別. Mysql 默許的事務(wù)隔離級別為: REPEATABLE READ
設(shè)置隔離級別
1).在 MySql 中設(shè)置隔離級別
每啟動1個 mysql 程序, 就會取得1個單獨的數(shù)據(jù)庫連接. 每一個數(shù)據(jù)庫連接都有1個全局變量 @@tx_isolation, 表示當(dāng)前的事務(wù)隔離級別. MySQL 默許的隔離級別為 Repeatable Read
查看當(dāng)前的隔離級別: SELECT @@tx_isolation;
設(shè)置當(dāng)前 mySQL 連接的隔離級別:
set transaction isolation level read committed;
設(shè)置數(shù)據(jù)庫系統(tǒng)的全局的隔離級別:
set global transaction isolation level read committed;
2).在 Hibernate 中設(shè)置隔離級別
JDBC 數(shù)據(jù)庫連接使用數(shù)據(jù)庫系統(tǒng)默許的隔離級別. 在 Hibernate 的配置文件中可以顯式的設(shè)置隔離級別. 每個隔離級別都對應(yīng)1個整數(shù):
1. READ UNCOMMITED
2. READ COMMITED
4. REPEATABLE READ
8. SERIALIZEABLE
Hibernate 通過為 Hibernate .cfg.xml映照文件指定 hibernate.connection.isolation 屬性來設(shè)置事務(wù)的隔離級別
<property name="connection.isolation">2</property>