Hibernate flush理解

skyarthur發表於2015-12-05

問題

在spring框架沒有事務的情況下,通過hibernate的session.save(entity),無法將資料持久化至資料庫中,即使強制重新整理後(flush())後也同樣如此。

原因

混淆了spring框架中事務和mysql事務的概念。對於增刪改操作,必須commit後才能持久化至mysql資料庫。若不commit,只有在同一個連線中才能看到最新的更改,對其他連線不可見。

擴充套件

Hibernate的flush

執行時會清除session快取並向資料庫傳送SQL語句並執行,但此時如果資料庫當前存在一個事務,資料庫會先將這些SQL語句快取起來,那麼此時在資料庫中是無法看到SQL語句執行結果的。除非執行commit提交了事務。只要沒有執行commit()方法,就能通過rollback()方法進行回滾。

Hibernate的commit

執行時會先隱式呼叫flush()方法,再提交事務。執行之後無法rollback()進行回滾。即commit操作才是真正的將實體資料持久化至資料庫。

總結

通過hibernate進行資料庫連線時,autocommit預設是false,因此僅僅做flush()是無法將資料持久化至資料庫的,必須顯式呼叫commit方法。
而如果使用jdbcTemplate進行資料庫連線的話,無需顯式執行commit方法,因為此時autocommit預設為true。通過以下程式碼驗證之:

Connection conn = DriverManager.getConnection(JdbcTest.URL, JdbcTest.USER, JdbcTest.PWD); // 通過JDBC進行連線
SessionFactory sFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory(); 
Session session = sFactory.openSession(conn); // 使用jdbc的連線初始化hibernate的session
System.out.println(session.connection().getAutoCommit()); // autoCommit預設為true

相關文章