我有一个关于Spring Data仓库如何处理数据源连接的问题。假设Spring Data仓库在方法执行时打开并关闭连接,那么通过在我的服务层声明@Transactional
开始的事务如何跨越多个仓库调用?
是谁负责处理数据库连接?@Transactional
注释还是JPA仓库?
我有一个关于Spring Data仓库如何处理数据源连接的问题。假设Spring Data仓库在方法执行时打开并关闭连接,那么通过在我的服务层声明@Transactional
开始的事务如何跨越多个仓库调用?
是谁负责处理数据库连接?@Transactional
注释还是JPA仓库?
最终,Spring JPA / 事务基础架构通过线程绑定的EntityManager
实例管理连接。事务的范围由用户代码中的@Transactional
注释控制,但最终在Spring Data JPA的存储库实现中进行默认设置。如果使用OpenEntityManagerInViewFilter
(在Spring Boot 1.x和2.x中默认启用),则会急切地执行连接获取。
SimpleJpaRepository
配备了 Spring 的 @Transactional
注解,以确保在需要 JPA 运行事务的情况下(例如执行调用EntityManager.persist(…)
或 ….merge(…)
),它将运行这些事务。它们的默认配置确保它们自动参与抽象级别较高的事务。也就是说,如果您有一个 Spring 组件本身被标记为 @Transactional
,则存储库将仅参与已经运行的事务中:
@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
的作用。OpenEntityManagerInViewFilter
。它用于创建EntityManager
并因此相当早地获取连接并保持到请求处理的最后阶段,即在视图呈现之后。这使得JPA懒加载可用于视图呈现,但会使连接保持打开时间比仅用于实际事务工作所需的时间更长。