文章出處

 問題1:到底該用getTransaction還是beginTransaction?

上圖說明的問題:

  • 第1步,調用session.getTransaction()的時候,會創建一個全新的Transaction對象;
  • 第2步,調用session.beginTransaction()的時候,會創建一個全新的Transaction對象,沒有使用上一步的Transaction對象哦;
  • 第3步,再次調用session.getTransaction()的時候,會看到這時返回的是第2步創建的Transaction對象;
  • 第4步,這時調用session.getCurrentTransaction(),會看到仍然返回第2步創建的Transaction對象;

結論:通常情況下一個session內只會處理一個事務,所以大多數時候可直接調用session.beginTransaction()方法創建一個全新的transaction對象,并開始該事務。 

 

 問題2:getCurrentTransaction跟getTransaction有什么區別?

上圖說明的問題:

  • 第1步,直接調用session.getCurrentTransaction()會返回null;
  • 第2步,調用session.beginTransaction() 會創建一個全新的Transaction對象;
  • 第3步和第4步說明,當session.beginTransaction()被調用后,不管使用session.getTransaction()還是session.getCurrentTransaction()都是返回beginTransaction時創建的同一個Transaction對象。

結論:當session.beginTransaction被調用之后,不管是用session.getTransaction還是getCurrentTransaction返回的都是同一個transaction對象;如果沒有開始事務,getTransaction會創建一個新的transaction對象,getCurrentTransaction會返回null。 

 

問題3:如果不斷的調用getTransaction,是否會返回同一個transaction對象?

結論:上圖說明,每次調用session.getTransaction()都會創建全新的Transaction對象,如果是這樣,那這個方法如果叫session.createTransaction()或許更加合理,但是呢,如果session已經有begin了的transaction,該方法又不會創建新的transaction。所以說,這個命名真的是一個巨大的坑,在程序中應該避免使用這個方法,否則難以理解是否是同一個Transaction對象;

 

問題4: 通過getTransaction創建的transaction對象begin之后,再次調用session.beginTransaction是否會開啟兩個事務?

 

結論:上圖說明,session.getTransaction().begin() 與 session.beginTransaction() 是完全一模一樣的。一個session同時只能有一個transaction是active的(開啟狀態)。

 

那么,既然一個session可以通過session.getTransaction()創建無數個Transaction實例,那么這些Transaction實例是否可以獨立工作呢?但是下方的最后一行代碼就報錯了:

Transaction transaction1 = db.getSession().getTransaction();
Transaction transaction2 = db.getSession().getTransaction();
transaction1.begin();
transaction2.begin();

原因就是一個session不能同時開啟多個transaction。

 

問題5:當transaction.commit()調用之后再次調用session.beginTransaction是否會繼續沿用之前的transaction? 

 

 上圖說明的問題:

  1. 一個session里面是可以開啟多個transaction的,但是一個transaction的begin方法只有在其他transaction都不是active的時候才可以調用成功,也就是說一個session同時僅允許一個active的transaction;
  2. 當一個transaction.commit() 方法調用之后,再次調用session.getTransaction()就會創建一個全新的Transaction對象,這一點非常重要,千萬不要以為同一個session在調用transaction.begin()之后再調用session.getTransaction()都只會返回同一個Transaction對象,如果之前begin的那個transaction已經commit,這時再調用session.getTransaction()就是全新的transaction對象了。

 

 問題6:是否總是需要手工調用transaction.rollback實現事務回滾?

問題:假如一個transaction.commit()方法提交了2條sql,但是第2條由于數據驗證錯誤而拋了異常,那么請問,如果不手工調用transaction.rollback()方法,該transaction的第1條sql是否會執行成功。

答案:不會執行成功。這個結論告訴我們,如果之前沒有調用session.flush()而是最后一起執行transaction.commit(),那么不需要加try-catch來手工調用transaction.rollback()

 

本文中的測試來自jframe 框架

基于spring mvc搭建的多層級多模塊java web應用程序框架。包含:基礎設施層、數據庫定義規范、數據庫訪問規范、日志記錄規范、多層級異常捕獲、標準ajax規范、母版頁規范、視圖呈現規范、JavaScript框架規范等。實際上該框架定義的規范極其詳細,比如數據庫定義層:枚舉類使用規范、datetime/bool/string字段規范、1對1、1對多、多對1、多對多外鍵關系映射規范、父類定義規范、字段注釋規范、懶加載規范等等。。。

 

技術交流QQ群:651499479,歡迎java大神指點迷津,也歡迎新手進群學習。

 

github地址: https://github.com/leotsai/jframe

 

THE END.

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()