[英]@Transactional Method Calling - should we pass objects as parameters?
@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
public void schoolProcessing{
//some logic here
save(student); //student is now managed
//some student update logic
}
我認為這是一個基本問題,但已經看過其他問題,但無法澄清。 謝謝。
簡短的答案:兩者都會起作用
長答案:
關於@Transactional
和事務傳播,有很多細節。 以下是有關大多數開發人員使用的最簡單方案的一些信息。
當組件/服務/控制器具有@Transactional
Spring會將其包裝在一個代理(思維裝飾器模式)中,該代理將創建線程本地狀態,以容納事務信息並將其鏈接到@PersistenceContext
EntityManagers
。 當代理完成對@Transactional
方法的調用時,它將提交事務。 由於此方法使用線程本地狀態,因此在@Transactional
方法內部使用的任何@PersistenceContext
注釋的EntityManager
或它調用的任何方法,即使其他bean中的方法也將共享相同的事務和持久性上下文。
為了更好地了解更新,讓我們看看在JPA中加載實體時會發生什么。 當您加載實體時,持久性上下文會保存一個副本,並且在事務提交時,它將遍歷所有托管實體,並將它們與加載時的副本進行比較,並以此為基礎確定要發送到哪個更新語句。數據庫。 因此,當您加載實體並對其進行修改時,您無需執行任何操作(除了讓事務提交),即可更新數據庫。 當您保留一個新實體時,將其添加到托管實體的內部集合中,並且如果將該實體發送給修改它的方法,則只要修改發生在事務提交之前,它也將最終存儲在數據庫中,並且實體變得分離。
這只是冰山一角,一旦您開始談論不同的傳播類型,手動調用刷新或觸發查詢前刷新的查詢,就會變得非常復雜。 以我的經驗,JPA是最被低估的Java技術之一,從表面上看它是如此簡單,但是如果您不了解基本原理,則可以花幾天的時間來了解/調試所得到的錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.