2013-07-06 109 views
8

Hibernate的docs顯示這個例子:休眠只讀事務

session = sessionFactory.openSession(); 
session.beginTransaction(); 
List result = session.createQuery("from Event").list(); 
for (Event event : (List<Event>) result) { 
    System.out.println("Event (" + event.getDate() + ") : " + 
     event.getTitle()); 
} 
session.getTransaction().commit(); 
session.close(); 

爲什麼要進行session.getTransaction().commit()即使在事件列表中只是被打印出來?

回答

11

SELECT還需要事務處理。沒有任何事務執行SELECT是不可能的。在使用某些SQL GUI工具從數據庫選擇數據時,您不必顯式啓動和結束事務,因爲這些工具正在使用autocommit模式。在自動提交模式下,數據庫將自動啓動併爲每條SQL語句提交事務,這樣您就不必顯式聲明事務邊界。

如果您未結束(即落實或回滾)事務,則此事務所使用的數據庫連接將不會被釋放,並且您的數據庫最終將耗盡可用連接。

對於休眠,它默認使用非自動提交模式(由屬性hibernate.connection.autocommit指定)。所以我們必須申報交易界限並確保交易結束。

但是,如果使用Hibernate API只查詢數據時,它是好的,即使你沒有明確聲明,因爲以下的事務邊界:

  1. 數據庫通常會自動啓動一個新的事務時,當前的SQL聲明需要一個,而且之前沒有明確啓動事務。

  2. Session.close()close()底層Connection。據JDBC規範,如果java.sql.Connection#close()被調用,並有一個活動的事務,這活動事務的結果依賴於JDBC供應商的實現。通常,JDBC驅動程序將自動提交或回滾此事務。但在這種情況下,由於您已經獲取了所需的數據,因此事務是否提交或回滾並不重要。

+0

感謝您的詳細解答 –