[英]How Spring+JPA integration actually works
一個簡單的銀行應用程序:
注意事項:
問題:
使用@PersistenceContext
注入的EntityManager
實例是將實際工作委托EntityManager
當前事務關聯的EntityManager
的代理。
換句話說,它的工作方式如下:
@Transactional
范圍時,將創建新事務並將其與當前線程關聯 EntityManager
的方法時,該調用將委派EntityManager
當前事務關聯的EntityManager
(如果不存在,則將創建新的EntityManager
) @Transactional
范圍時,事務將被提交,並且與其關聯的EntityManager
被關閉 使用@PersistenceContext
注入DAO的實際上不是底層ORM的Entity Manager實現,而是Spring代理,它將把調用委派給實際的底層實體管理器。 代理的具體類通常是SharedEntityManagerInvocationHandler
。
基礎實體管理器的范圍通常是Spring托管事務的范圍(另一個是擴展范圍,在這里是沒有問題的)Spring事務管理器(當JPA用作數據訪問時通常是JpaTransactionManager)將EntityManager綁定到當前線程然后從這里檢索實體管理器,直到事務提交。 對於新交易,同樣的事情也會發生。 您可以看一看JpaTransactionManager doBegin
方法的源代碼。
基於您提供的解密技術,您正在將Spring與EclipseLink一起用作JPA提供程序,並且可能正在將J2EE容器用於您的Web應用程序,並且基於我的猜測,我認為這是一篇有關事情如何工作的好文章。
基本概念 :
- EntityManager-管理實體的持久狀態(或生命周期)的類。
- 持久性單元-是實體類的命名配置。
- 持久性上下文-是一組托管的實體實例。 實體類是持久性單元配置的一部分。
- 托管實體-如果實體實例是持久性上下文的一部分,並且該實體管理器可以對其執行操作,則該實體實例將受到管理。
根據本文,您可以通過@PersistenceContext使用容器管理的EntityManager
當應用程序的一個容器(例如Java EE容器或任何其他自定義容器,例如Spring)管理實體管理器的生命周期時,該實體管理器被稱為“容器管理”。 獲取容器管理的EntityManager的最常見方法是在EntityManager屬性上使用@PersistenceContext批注。
注入是這樣的:
每當解析由@PersistenceContext創建的引用時,都會返回事務作用域實體管理器。
和
每次在實體管理器上調用操作時,容器代理(容器在實例化時在實體管理器周圍創建一個代理)都會檢查JTA事務上是否存在任何持久性上下文。 如果找到一個,則實體管理器將使用此持久性上下文。 如果找不到,則將創建一個新的持久性上下文並將其與事務關聯。
因此,實體管理器的生命周期由您的容器和
我們使用EntityManager的實例,EntityManager的唯一作用是確定持久性上下文的生存期。 它在決定持久化上下文的行為時不起作用。 重申一下,持久性上下文是一組實體實例的托管集合。 每當事務開始時,Persistence Context實例都會與之關聯。 當事務結束時(例如,提交),持久性上下文將被刷新並與事務解除關聯。
簡而言之,您可以通過EntityManagerFactory實例化EntityManager來提供和管理其生命周期,但可以為您注入EntityManager的代理。 TransactionManager負責根據您提供的注釋創建,提交和...事務,無論何時開始事務,與之關聯的PersistancecContext以及事務結束時都會提交PersistenceContext狀態。 EntityManager與PersistenceContext一起使用,如果未提供,則EntityManager創建一個。 只要EntityManager不持有任何狀態並且該狀態(PersistenceContext)附加到當前事務,則它是線程安全的。
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.