2017-05-02 71 views
0
@Transactional 
public void schoolProcessing{ 
    //some logic here 
    save(student); //student is now managed 
    //Calling update student 
    updateStudent(student) or updateStudent(); 
    //which of the above is the correct way 
} 

public void updateStudent(Student student) { 
    //some student update logic 
} 

在JPA的@Transactional方法中調用方法時,我們是否應該將管理實體作爲參數傳遞?或者是因爲這被標記爲@Transactional,JPA無縫處理所有持久性,就好像所有從@Transactional調用的方法都在同一個方法中一樣?@Transactional方法調用 - 我們應該傳遞對象作爲參數嗎?

爲了澄清,上面的代碼在所有方面是否與以下相同。

@Transactional 
public void schoolProcessing{ 
    //some logic here 
    save(student); //student is now managed 

    //some student update logic 
} 

我認爲這是一個基本問題,但已經看到其他問題,但無法弄清楚。謝謝。

回答

1

答案很簡單:雙方將合作

長的答案:

有很多的細節,當談到@Transactional和事務傳播。以下是有關大多數開發人員使用的最簡單場景的一些信息。

當組件/服務/控制器具有@Transactional Spring將它包裝在一個代理(認爲Decorator模式),這將創建線程局部狀態,房交易信息,並將其鏈接到@PersistenceContextEntityManagers。當代理完成對@Transactional方法的調用時,它將提交交易。由於這使用線程本地狀態,所以在@Transactional方法或其調用的任何方法中使用@PersistenceContext註釋EntityManager,即使其他bean中的方法也將共享相同的事務和持久性上下文。

爲了更好地理解更新,我們來看看實體在JPA中加載時會發生什麼。當你加載一個實體時,持久化上下文會保存一個副本,當事務提交時,它會遍歷所有的被管實體,並將它們與加載時的副本進行比較,基於這一點,它計算出哪些更新語句發送給數據庫。所以當你加載一個實體並修改它時,你不必做任何事情(除了讓事務提交)來更新數據庫。當你堅持一個新的實體時,你將它添加到管理實體的內部集合中,如果你發送實體到一個修改它的方法,那麼這個實體也會在數據庫中結束,只要修改發生在事務提交之前,並且實體變得分離。

這只是冰山的頂峯,一旦你開始談論不同的傳播類型,手動調用刷新或觸發預查詢刷新的查詢,它可能會變得非常複雜。根據我的經驗,JPA是最被低估的Java技術之一,表面上看起來非常簡單,但如果您不瞭解基本原理,則可以花費數天時間來了解/調試所獲得的錯誤。

相關問題