2010-09-26 60 views
8

我正在用hibernate和jsp/servlet編寫一個基於Web的應用程序。我已閱讀有關sessionFactory.getCurrentSessionsessionFactory.openSession方法。我知道他們之間的基本區別(使用getCurrentSession您不必關閉連接,並且在您提交事務時,您的會話將自動關閉)。根據我的理解,我們應該選擇getCurrentSession並通過每次請求會話來完成。
getCurrentSession在網頁中休眠

讓我們考慮以下情形:

  1. 方法A調用getCurrentSession並獲得本屆
  2. 在方法A,一個事務使用步驟1
  3. 方法的會話啓動A呼叫方法B,其也具有getCurrentSession並開始交易
  4. 方法B提交其轉賬saction
  5. 控制返回到方法的同時也提交事務

現在我的問題是

  1. 將在本屆會議在步驟1中找到和第3步將是相同的會議?
  2. 如果問題1的答案是肯定的,那麼它將如何處理步驟4中的提交?理想情況下,它應該關閉本身的會話,並應該在第5步拋出異常。
  3. 如果問題1的答案爲否,那麼您如何處理這種情況?

回答

6

我沒有針對您的方案的答案,因爲我不會以這種方式實施它,因爲它似乎要求麻煩。相反,我會在C中啓動事務,其中C調用A和B,並讓C發出提交。骨骼:

public void c(...) { 
    try { 
     transaction.begin(); 
     a(); 
     b(); 
     transaction.commit(); 
    catch (Exception e) { 
     transaction.rollback(); 
    } 
} 

所以在這裏,a()b()不提交或回滾 - 他們是如何知道整個業務任務已經完成?他們可以拋出一個異常,或者返回一個布爾值來告訴調用者有什麼不對勁,並且需要回滾。

+0

謝謝託尼,我喜歡你提到的方式。 – Aashutosh 2010-09-27 09:13:57

+0

@託尼恩尼斯:加上一個,真的很精簡。 – 2015-01-25 17:38:00

7

在步驟1和步驟3中找到的會話會是同一個會話嗎?

他們應該是相同的,這是莫名其妙的getCurrentSession()合同的一部分,你會得到綁定到線程,只要工作單位Session尚未完成(即一個事務被提交或回滾)。 Java持久性與Hibernate把它像這樣(p.481):

所有這一切在調用getCurrentSession()的數據訪問代碼的全局共享 SessionFactory能存取相同的電流Session - 如果這就是所謂的 同一個線程。當Transaction被提交(或回滾)時,工作單元完成。如果您提交或回滾事務,Hibernate也會刷新並關閉當前的Session及其持久化上下文。這意味着在提交或回滾之後調用getCurrentSession()會產生新的Session和新的持久性上下文。

而且您可能還想要了解Session#beginTransaction()的javadoc所說的內容。

如果問題1的答案是肯定的,那麼如何將它處理在步驟4理想情況下,提交應該有關閉會話本身,並應在第5步

步驟給錯誤4應該不是問題,Session將被刷新,Transaction將被提交併且Session關閉。但我預計步驟5會失敗TransactionException(這是我的賭注)。但讓我引用javadoc Transaction

事務與會話相關聯,並且通常通過調用Session.beginTransaction()來實例化。單個會話可能跨越多個事務,因爲會話的概念(應用程序和數據存儲之間的對話)比事務概念的粒度更粗。然而,的意圖是在任何時間最多隻有一個與特定會話相關聯的未提交的交易

正如上面強調的,我們正在討論一些不應該發生的事情(即設計問題)。