具有长时间运行请求的 Spring 启动连接池



当 Spring 引导请求启动时,它会从池中获取连接。我的问题是 - 此连接是否仍然绑定到请求线程(即使它没有执行任何查询(并且仅在请求完成时才返回到池中?

例如,如果我正在做这样的事情:

  1. 请求开始
  2. 执行查询(20 毫秒(
  3. 调用外部 http 服务(1500ms(
  4. 请求完成

此请求线程获得的连接是否会在 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((。所以在这方面,"基础设施强加的连接时间限制"是+无穷大

最新更新