当 Spring 引导请求启动时,它会从池中获取连接。我的问题是 - 此连接是否仍然绑定到请求线程(即使它没有执行任何查询(并且仅在请求完成时才返回到池中?
例如,如果我正在做这样的事情:
- 请求开始
- 执行查询(20 毫秒(
- 调用外部 http 服务(1500ms(
- 请求完成
此请求线程获得的连接是否会在 20 毫秒或 1520 毫秒内保持线程占用(并且对其他请求不可用(?
PS:我正在使用带有HikariCP的Spring Boot 2.0,我没有使用@Transactional。
谢谢。
如果你的类路径上有Spring MVC,Spring会自动配置一个OpenEntityManagerInViewInterceptor
实例(org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.JpaWebConfiguration
(,除非你spring.jpa.open-in-view
配置为false。此侦听器将打开EntityManager
的实例,并在整个请求期间将其绑定到TransactionSynchronizationManager
。
这意味着在第一次使用存储库查询时,它将从池中借用连接,并将其保留到拦截器关闭EntityManager
的请求结束时。EntityManager
负责将连接返回到池中。因此,在这种情况下,在您的示例中,连接将被借用 1520 毫秒。
如果禁用spring.jpa.open-in-view
选项,则每次使用存储库查询时都会借用并返回连接,前提是您不使用任何显式事务。虽然这可能看起来更好,但您必须记住,需要在每个持久操作上系统地重新附加实体的托管实例,因此成本可能很高。您还将失去EntityManager
缓存的好处。若要避免这种情况,请使用事务来读取/修改/保留实体并避免重新附加。
最后,请记住,如果您禁用spring.jpa.open-in-view
,由于您在请求期间没有EntityManager
,因此您需要确保将延迟加载的关系加载到事务中,否则您将获得可怕的LazyInitializationException
。
基本上这取决于,
如果您关闭连接,它将释放回池,并将根据配置(如下(很快准备就绪,因此它将是~20ms(+返回池的时间(
如果您不关闭连接,它将等到配置允许它,如果它允许无限期的时间,理论上它可能会导致您的应用程序泄漏,并且在 apllication 关闭之前不会返回池。
请参阅有关 Hikari 处理返回池连接的答案:
光管家每 30 秒运行一次,这会关闭任何未使用且早于 maxLife 的连接。如果连接数超过最小值,管家将关闭空闲时间超过空闲超时的连接。
查看有关最长连接寿命的更多信息:
默认情况下,Oracle 不强制要求连接的最大生存期(无论是在 JDBC 驱动程序端 (1( 上,还是在服务器端 (2((。所以在这方面,"基础设施强加的连接时间限制"是+无穷大