tl; dr
最终,这是Spring JPA /事务基础结构通过EntityManager实例的广告绑定管理来管理连接.事务的范围由用户代码中的@Transactional注释控制,但最终在Spring Data JPA的存储库实现中默认.万一使用OpenEntityManagerInViewFilter(在Spring Boot 1.x和2.x中默认启用),将急切地执行连接获取.
细节
SimpleJpaRepository配备了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实例的生存期内获取连接.有关详细信息,请参见JpaTransactionManager.doBegin(…).
OpenEntityManagerInViewFilter或–Interceptor的作用
除非明确停用,否则Spring Boot 1.x和2.x Web应用程序将在部署了OpenEntityManagerInViewFilter的情况下运行.它用于创建EntityManager,从而很早地获取连接并将其保持到请求处理的最后阶段,即在呈现视图之后.这具有JPA延迟加载可用于视图呈现的效果,但与仅实际事务工作所需的连接相比,开放连接的时间更长.
该主题相当具象controversial one,因为它在开发人员便利性(在视图呈现阶段遍历对象关系以延迟加载的能力)之间的棘手平衡,冒着触发昂贵的附加查询和使资源长时间使用的风险. .