我对Spring Data存储库如何处理数据源连接有疑问。假设Spring Data存储库打开和关闭连接以及方法执行时的连接,通过在服务层中声明@Transactional
来启动的事务如何跨越多个存储库调用?
谁处理数据库连接? @Transactional
批注还是JPA存储库?
答案 0 :(得分:3)
最终,这是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,因为它在开发人员便利性(在视图呈现阶段遍历对象关系以延迟加载的能力)之间的棘手平衡之间存在着触发昂贵的附加查询并保持资源使用时间更长。