hibernate 中的session和事務(Transaction)

在使用hibernate開發時,遇到最多的就是session與事務,那麼他們兩個有什麼關係呢?下面我來拋磚引玉:java

        一、session是hibernate中的以及緩存機制,是用來對數據進行增刪改查的一個東西(具體是什麼我也不是很清楚,能夠理解爲是用來操做數據的)mysql

        二、事務是一組操做單元的集合,用的比較多的是conmmit和rollback這兩個方法,前面的提交後面的回滾。sql

        先看下面的兩段代碼:數據庫

        代碼1:緩存

        Configuration config = new  Configuration().configure("com/ebookstore/config/hibernate.cfg.xml");
        Session session = config.buildSessionFactory().openSession();
  session

        Transaction tran=session.beginTransaction(); 
        tran.begin();框架

 

        session.save(object);
        tran.commit();
        session.flush();測試

           代碼2:ui

        Configuration config = new  Configuration().configure("com/ebookstore/config/hibernate.cfg.xml");
        Session session = config.buildSessionFactory().openSession();
  spa

        Object obj = session.get(dtoclass, id);
         session.flush();

            代碼1:用到了事務,而代碼二呢沒有,這是怎麼緣由呢?咱們能夠從兩個方面去理解:

            一、在對數據進行查找時,即便你失敗並不影響數據庫中的數據;在對數據庫進行添加時,那就不一樣了,當你添加數據失敗時,可能會在數據庫中留下垃圾數據。這是咱們就要用到事務,事務他提交失敗時,他就會自動回滾。這樣就不影響數據庫了。

            二、在對hibernate框架使用時,你不從新開啓事務的話,你是不能對數據進行增刪改的,由於事務默認爲是失敗的,也就是數他一直處於回滾狀態。因此你每次操做都是不成功的!

 

            說了這麼多,就是一句話,使用hibernate進行增刪改是要從新開啓事務,使用查詢時能夠不用從新開啓事務!

 

2、

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)後面加一行代碼,輸出這個customer的OID,System.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,由於通常狀況下臨時對象的OID是NULL。

 

接着咱們作兩個測試

 

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

 

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

 

經過查閱HibernateAPI能夠知道flush方法的主要做用就是清理緩存,強制數據庫

 

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

相關文章
相關標籤/搜索