Spring Boot 中的 PersistenceContext 生命周期
Posted
技术标签:
【中文标题】Spring Boot 中的 PersistenceContext 生命周期【英文标题】:PersistenceContext lifecycle in Spring Boot 【发布时间】:2021-06-14 01:03:57 【问题描述】:我试图理解 Spring Boot 应用程序中的持久性上下文是如何工作的。我使用 Spring Data、Hibernate 和 Hikari。
我不知道PersistenceContext
何时创建以及何时关闭。根据几篇文章,例如https://www.baeldung.com/jpa-hibernate-persistence-context 或https://dzone.com/articles/how-does-spring-transactional 这一PersistenceContext
生命周期与EntityManager
生命周期相同。所以我想知道,当EntityManager
实际创建时,它关闭时更重要,最重要的是它在事务结束时关闭。根据我的发现,枚举PersistenceContextType.java
决定了我将拥有什么PersistenceContext
。 PersistenceContextType.TRANSACTION
应该是默认的,应该导致 SharedEntityManagerInvocationHandler
被用作 EntityManager
的实现并且应该在事务结束时关闭,而 PersistenceContextType.EXTENDED
应该比事务更有效并且应该导致 @正在使用 987654333@。所以我尝试通过调试来证明它,我发现了以下内容。
PersistenceContextType.EXTENDED
没有在任何地方进行评估。 PersistenceAnnotationBeanPostProcessor.java
有一些用法,但是在我的集成测试中断点从未停止过。
有时会调用SharedEntityManagerInvocationHandler#invoke
,有时会调用ExtendedEntityManagerInvocationHandler#invoke
,但这并不能告诉我它使用的是哪种EntityManager
。
在某些情况下,我什至发现SharedEntityManagerInvocationHandler
包装了ExtendedEntityManagerInvocationHandler
。
问题是 - 如何确定PersistenceContext
在交易结束时是否关闭?
【问题讨论】:
【参考方案1】:
PersistenceContextType.EXTENDED
没有在任何地方进行评估。PersistenceAnnotationBeanPostProcessor.java
有一些用法,但是在我的集成测试中断点从未停止过。
当您的任何 bean 中有以下字段声明时,您将遇到断点:
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;
问题是——如何确定 PersistenceContext 是否在事务结束时关闭?
有趣的问题。如果您仔细研究一下 Spring 代码,您会注意到 SharedEntityManagerInvocationHandler
调用了 EntityManagerFactoryUtils.doGetTransactionalEntityManager()
。该方法为返回的EntityManager
实例注册一个事务同步:
TransactionSynchronizationManager.registerSynchronization(
new TransactionalEntityManagerSynchronization(emHolder, emf, transactionData, false));
该同步是在事务后关闭EntityManager
:
protected void releaseResource(EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey)
closeEntityManager(resourceHolder.getEntityManager());
您还会注意到,ExtendedEntityManagerInvocationHandler
并没有这样做。
【讨论】:
以上是关于Spring Boot 中的 PersistenceContext 生命周期的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot2 系列教程(十三)Spring Boot 中的全局异常处理
Spring Boot2 系列教程Spring Boot 中的静态资源配置