jpa - 如何为 Spring Data JPA 存储库管理数据库连接?
问题描述
我有一个关于 Spring Data 存储库如何处理数据源连接的问题。假设 Spring Data 存储库在方法执行时打开和关闭连接以及连接,那么通过在我的服务层中声明的事务如何@Transactional
跨多个存储库调用启动?
谁处理数据库连接?@Transactional
注释还是 JPA 存储库?
解决方案
tl;博士
EntityManager
最终是 Spring JPA / Transaction 基础设施通过实例的绑定管理来管理连接。事务的范围由@Transactional
用户代码中的注释控制,但最终默认在 Spring Data JPA 的存储库实现中。在使用an 的情况下会急切地执行连接获取OpenEntityManagerInViewFilter
(在 Spring Boot 1.x 和 2.x 中默认启用)。
细节
SimpleJpaRepository
配备了 Spring 的@Transactional
注解,以确保它在 JPA 需要它们的情况下运行事务(例如,执行对EntityManager.persist(…)
or的调用….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 公开的事务管理 API来启动事务并在实例EntityManager
的生命周期内获取连接。EntityManager
详情请参阅JpaTransactionManager.doBegin(…)
。
OpenEntityManagerInViewFilter
一个或的角色–Interceptor
除非显式停用,否则 Spring Boot 1.x 和 2.x Web 应用程序将在已OpenEntityManagerInViewFilter
部署的情况下运行。它用于在EntityManager
很早的时候创建一个连接并因此获得一个连接,并将其保留到请求处理的很晚,即在视图呈现之后。这具有 JPA 延迟加载可用于视图呈现的效果,但保持连接打开的时间比仅用于实际事务工作的时间长。
该主题是一个颇具争议的话题,因为它在开发人员便利(在视图渲染阶段遍历对象关系以延迟加载的能力)之间的微妙平衡,冒着触发昂贵的额外查询和保持资源使用更长时间的风险时间。
推荐阅读
- android-studio - 如何制作开发阶段/文档 - 用于上传到任何网站的 Android Studio 应用的 PDF
- python - 我有文本文件,我想提取在某个单词之后继续并在另一个单词之前结束的数据。我该怎么做这条蟒蛇?
- javascript - 将对象转换为文件
- python - ValueError: blocks[0,:] 的行尺寸不兼容
- azure - 时间序列洞察(预览版):建模为分类变量的最大误差。100
- arrays - numpy:非结构化数组到结构化数组
- python - 如何将网络摄像头拍摄的图像保存到特定位置
- python - 使用 DTW 对齐视频序列
- json - 使用sql存储过程获取json字符串中的子节点?
- codeigniter - 在codeigniter中获取两个日期之间的小时和天差