Spring数据JPA存储库如何管理数据库连接?

Spring数据JPA存储库如何管理数据库连接?,jpa,transactions,spring-data-jpa,spring-data,Jpa,Transactions,Spring Data Jpa,Spring Data,我有一个关于Spring数据存储库如何处理数据源连接的问题。假设Spring数据存储库在方法执行时打开和关闭连接以及连接,那么通过在我的服务层中声明@Transactional来启动事务如何跨越多个存储库调用 谁处理数据库连接?@Transactional注释或JPA存储库?tl;博士 最终是Spring JPA/Transaction基础设施通过EntityManager实例的绑定管理来管理连接。事务的范围由用户代码中的@Transactional注释控制,但最终在SpringDataJPA的

我有一个关于Spring数据存储库如何处理数据源连接的问题。假设Spring数据存储库在方法执行时打开和关闭连接以及连接,那么通过在我的服务层中声明
@Transactional
来启动事务如何跨越多个存储库调用

谁处理数据库连接?
@Transactional
注释或JPA存储库?

tl;博士 最终是Spring JPA/Transaction基础设施通过
EntityManager
实例的绑定管理来管理连接。事务的范围由用户代码中的
@Transactional
注释控制,但最终在SpringDataJPA的存储库实现中默认。如果使用了
OpenEntityManagerInViewFilter
(在Spring Boot 1.x和2.x中默认启用),则会急切地执行连接获取

细节 配备了Spring的
@Transactional
注释,以便确保在JPA需要时运行事务(例如,执行对
EntityManager.persist(…)
…merge(…)
)的调用)。它们的默认配置确保它们自动参与从更高抽象级别开始的事务。也就是说,如果您有一个本身是
@Transactional
的Spring组件,那么存储库只需参与已经运行的事务:

@Component
class MyService {

  private final FirstRepository first;
  private final SecondRepository second;

  // Constructor omitted for brevity

  @Transactional
  void someMethod() {

     … = first.save(…);
     … = second.save(…);
  }
}
两个存储库都参与事务,其中一个存储库出现故障将回滚整个事务

为了实现这一点,
JpaTransactionManager
将使用JPA的
EntityManager
公开的事务管理API来启动事务,并在
EntityManager
实例的生命周期内获取连接。有关详细信息,请参阅

OpenEntityManagerInViewFilter
拦截器的角色
除非显式停用,否则Spring Boot 1.x和2.x web应用程序在部署了
OpenEntityManagerViewFilter
的情况下运行。它用于创建一个
EntityManager
,从而很早就获得一个连接,并将其保留到请求处理的很晚,即在视图呈现之后。这具有JPA延迟加载可用于视图渲染的效果,但保持连接打开的时间比仅用于实际事务工作的时间长


这是一个相当复杂的话题,因为它在开发人员的便利性(在视图渲染阶段遍历对象关系以延迟加载的能力)与触发昂贵的额外查询和保持资源更长时间使用的风险之间存在微妙的平衡。

嗨,奥利弗,谢谢你的解释。因此,OpenEntityManagerViewFilter对于延迟加载是活动的,即使响应是Json/Xml格式的,对吗?我同意我不应该在响应转换中使用实体大多数时候,响应是基于某些实体状态呈现的,例如,实体可能只是转发给Jackson进行Json编组。在这些情况下,您必须确保关联在呈现过程中是可遍历的。如果使用Jpa实体,那么在json序列化过程中所有惰性集合都会初始化,这不会影响服务延迟吗?