簡體   English   中英

Hibernate Java中的會話和事務

[英]Session and Transaction in Hibernate Java

在Java Hibernate中,當我們需要對DB做一些事情時,我們需要:1。打開會話2.開始事務3.完成事務4.關閉會話

  • 例如,如果我想獲得學生列表:

     public static List<Student> getStudentList() { List<Student> l = null; Session session = HibernateUtil.getSessionFactory().openSession(); try { String hql = "from Student"; Query query = session.createQuery(hql); l = query.list(); } catch (HibernateException ex) { //Log the exception System.err.println(ex); } finally { session.close(); } return l; } 
  • 插入一名學生

     public static boolean addStudent(Student s) { Session session = HibernateUtil.getSessionFactory().openSession(); if (... /* check if student is already exists*/) { return false; } Transaction transaction = null; try { transaction = session.beginTransaction(); session.save(s); transaction.commit(); } catch (HibernateException ex) { //Log the exception transaction.rollback(); System.err.println(ex); } finally { session.close(); } return true; } 

為什么getStudentList()中沒有事務? 預先感謝

這篇hibernate 文章解釋了未在事務中顯式執行的SELECT操作的行為。

本文給出了以下示例,但對於您的查詢示例也是如此。

會話會話= sessionFactory.openSession();
session.get(Item.class,123l);
session.close();

  1. 將打開一個新會話。 此時它不會獲得數據庫連接。
  2. 對get()的調用會觸發SQL SELECT。 Session現在從連接池獲取JDBC連接。 默認情況下,Hibernate會立即使用setAutoCommit(false)關閉此連接上的自動提交模式。 這有效地啟動了JDBC事務!
  3. SELECT在此JDBC事務中執行。 會話關閉,連接返回到池並由Hibernate釋放 - Hibernate在JDBC Connection上調用close()。 未提交的交易會發生什么?

這個問題的答案是,“它取決於!”在連接上調用close()時,JDBC規范沒有說明掛起事務的任何內容。 發生的情況取決於供應商如何實施規范。 例如,使用Oracle JDBC驅動程序,對close()的調用將提交事務! 當JDBC Connection對象關閉並且資源返回到池時,大多數其他JDBC供應商采用相同的路由並回滾任何掛起的事務。 顯然,對於SELECT [...]這不會是一個問題

讓我們擴展上面的例子來引發一個可能的問題。

Session session = sessionFactory.openSession();
Item item = session.get(Item.class, 123l);
item.setPrice(10);
session.close();

現在,如果Item的新價格是否持久,它依賴於JDBC驅動程序。

因此,只要沒有數據庫更改,即使JDBC驅動程序將回滾事務,您也可以忽略純SELECT操作的開始和提交事務。

但無論如何,我強烈建議在任何操作上使用交易以避免誤解和問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM