Hibernate session flush commit

session.flush(): execute the SQL statements needed to synchronize the JDBC connection's
state with the state of objects held in memory.
This process, flush, occurs by default at the following points
• before some query executions
• from org.hibernate.Transaction.commit()
• from Session.flush()

處於persistent狀態的bean,如果在session close之前,沒有調用session.flush() 那麼它的數據不會持久化到數據庫中,即使做了commit(); 不過有一種情況比較特殊,就是transaction.commit()會先調用session.flush()方法。

sessionsave方法爲例來看一個簡單、完整的事務流程,如下是代碼片段:

…………………………………………………………………………

Session session = sessionFactory.openSession();

Transaction tx = session.beginTransaction();

session.save(customer);//之前已實例化好了的一個對象

tx.commit();

…………………………………………………………………………

示例很簡單,就是向數據庫中插入一條顧客信息,這是一個最簡單的數據庫事務。在這個簡單的過程中,Hibernate爲我們做了一些什麼事情呢?爲了更好的觀察,我們將Hibernateshow_sql屬性設置爲true,然後運行我們的程序,控制檯打印出如下信息:

Hibernate: select max(ID) from CUSTOMER

Hibernate: insert into CUSTOMER (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, description, BIRTHDAY, REGISTERED_TIME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

這裏也許看不出什麼端倪來,現在在session.save(customer)後面加一行代碼,輸出這個customerOIDSystem.out.println(customer.getId()),再次運行程序,控制檯輸出爲:

Hibernate: select max(ID) from CUSTOMER

22

Hibernate: insert into CUSTOMER (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, description, BIRTHDAY, REGISTERED_TIME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

OIDinsert語句之前輸出,這可以說明兩個問題:1.insert語句並不是在執行save的時候發送給數據庫的;2.insert語句是在執行commit的時候發送給數據庫的。結合前面我們所說過的:執行save的時候,Hibernate會首先把對象放入緩存,然後計劃一條insert語句。一個基本的插入流程就出來了:

1.  判斷所要保存的實例是否已處於持久化狀態,如果不是,則將其置入緩存;

2.  根據所要保存的實例計劃一條insert sql語句,注意只是計劃,並不執行;

3.  事務提交時執行之前所計劃的insert語句;

後臺還打印出了select max(ID) from CUSTOMER,這主要是爲了給customer賦予一個OID,因爲一般情況下臨時對象的OIDNULL

接着我們做兩個測試:

1.  tx.commit();註釋掉,此時控制檯沒有打印出insert語句;

2.  tx.commit()換成session.flush,此時控制太打印出了insert語句,但是數據庫中並沒有添加新的記錄;

通過查閱HibernateAPI可以知道flush方法的主要作用就是清理緩存,強制數據庫

Hibernate緩存同步,以保證數據的一致性。它的主要動作就是向數據庫發送一系列的sql語句,並執行這些sql語句,但是不會向數據庫提交。而commit方法則會首先調用flush方法,然後提交事務。這就是爲什麼我們僅僅調用flush的時候記錄並未插入到數據庫中的原因,因爲只有提交了事務,對數據庫所做的更新纔會被保存下來。因爲commit方法隱式的調用了flush,所以一般我們都不會顯示的調用flush方法。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章