閱讀123 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Hibernate的session中的flush

 

什麼是Hibernate Session刷出(flush)?也許大家對此不夠了解,但相信你看完本文一定有很大的收益。

每間隔一段時間,Session會執行一些必需的SQL語句來把內存中的對象的狀態同步到JDBC連接中。這個過程被稱為Hibernate Session刷出(flush)。

 

默認會在下麵的時間點執行:

 

◆在某些查詢執行之前

◆在調用org.hibernate.Transaction.commit()的時候

◆在調用Session.flush()的時候

◆涉及的SQL語句會按照下麵的順序發出執行:

◆所有對實體進行插入的語句,其順序按照對象執行Session.save()的時間順序

◆所有對實體進行更新的語句

◆所有進行集合刪除的語句

◆所有對集合元素進行刪除,更新或者插入的語句

◆所有進行集合插入的語句

◆所有對實體進行刪除的語句,其順序按照對象執行Session.delete()的時間順序

(有一個例外是,如果對象使用native方式來生成ID(持久化標識)的話,它們一執行save就會被插入。)

 

除非你明確地發出了flush()指令,關於Session何時會執行這些JDBC調用是完全無法保證的,隻能保證它們執行的前後順序。 當然,Hibernate保證,Query.list(..)絕對不會返回已經失效的數據,也不會返回錯誤數據。

 

也可以改變默認的設置,來讓Hibernate Session刷出(flush)操作發生的不那麼頻繁。 FlushMode類定義了三種不同的方式。僅在提交時刷出(僅當Hibernate的Transaction API被使用時有效), 按照剛才說的方式刷出,以及除非明確使用flush()否則從不刷出。最後一種模式對於那些需要長時間保持Session為打開或者斷線狀態的長時間運行的工作單元很有用。

 

sess = sf.openSession(); 
Transaction tx = sess.beginTransaction();

 

// allow queries to return stale state  
sess.setFlushMode(FlushMode.COMMIT);  
Cat izi = (Cat) sess.load(Cat.class, id); 
izi.setName(iznizi); 
 
// might return stale data 
sess.find("from Cat as cat left outer join cat.kittens kitten"); 
 
// change to izi is not flushed!

tx.commit(); // flush occurs 

sess.close();

 

Hibernate Session刷出(flush)期間,可能會拋出異常。(例如一個DML操作違反了約束)異常處理涉及到對Hibernate事務性行為的理解,這裏在事務和並發中有具體的介紹,這裏我們就不加以介紹了。

 

還有一種情況很值得我們注意——插入大量數據的時候

例如,我現在要插入10000個User,咋辦?

很多人會想這樣:

Transaction tx = session.beginTransaction();

for(int i=0;i<10000;i++)

{

    User u = new User(......);

    session.save(u);

}

tx.commit();

session.close();

 

但隨著程序的運行,總會在某一個時間點失敗。並且拋出OutOfMemoryException(內存溢出)異常!

這是因為Hibernate的session持有一個必選的一級緩存,所有的User實例都將在session級別的緩存區進行緩存。但緩存區“裝不下了”。

 

那麼如何解決?

解決方案:定時將session的緩存刷入數據庫!

for(int i=0;i<10000;i++)

{

    User u = new User(......);

    session.save(u);

    for(i ==0)

    {

        session.flush();

        session.close();

    }

}

tx.commit();

session.close();

 

參考地址:https://developer.51cto.com/art/200909/153860.htm

最後更新:2017-04-03 20:19:32

  上一篇:go Hibernate聯合主鍵
  下一篇:go iBATIS批量操作