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

时间:2018-10-22 07:38:47

标签: spring spring-boot hikaricp

弹簧启动请求开始时,它将从池中获得连接。我的问题是-此连接是否仍与请求线程保持联系(即使它没有执行任何查询),并且仅在请求完成时才返回到池中?

例如,如果我正在做类似的事情:

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

此请求线程获得的连接是否会在20ms或1520ms内被该线程占用(对其他请求不可用)?

PS:我正在将Spring Boot 2.0与HikariCP一起使用,而没有使用@Transactional。

谢谢。

2 个答案:

答案 0 :(得分:3)

如果您的类路径上有Spring MVC,除非您将OpenEntityManagerInViewInterceptor配置为false,否则Spring将自动(在org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.JpaWebConfiguration中配置spring.jpa.open-in-view的实例。该拦截器将打开EntityManager的一个实例,并将其绑定到TransactionSynchronizationManager的整个请求期间。

这意味着在第一次使用存储库查询时,它将EntityManager拦截器关闭时从池中借用连接并保持连接直到请求结束。将连接返回到池是EntityManager的责任。因此,在这种情况下,您的示例将借用1520毫秒的连接。

如果禁用spring.jpa.open-in-view选项,则在不使用任何显式事务的情况下,每次使用存储库查询时,都会借用并返回一个连接。虽然这看起来更好,但您必须记住,实体的托管实例将需要在每个持久性操作上系统地重新附加,因此可能会造成高昂的代价。您还将失去EntityManager缓存的好处。为避免这种情况,请使用事务来读取/修改/保留您的实体,并避免重新附着。

最后,请记住,如果禁用spring.jpa.open-in-view,由于在请求期间您没有EntityManager,因此您需要确保已加载了惰性加载的关系在交易内部,否则您将得到可怕的LazyInitializationException

答案 1 :(得分:0)

基本上取决于,

如果您关闭连接,它将被释放回池中,并且根据配置(如下所示)将很快准备就绪,因此大约需要20ms(加上返回池的时间)

如果不关闭连接,它将等待直到配置允许它,如果允许无限的时间,从理论上讲,这可能会导致应用程序泄漏,并且在关闭合并之前不会返回到池中。

请参见answer,了解Hikari处理返回池的连接的情况:

  

Hikari管家每30秒运行一次,这将关闭所有未使用且早于maxLifetime的连接。如果连接的连接数超过minimumIdle,管家将关闭空闲时间超过idleTimeout的连接。

详细了解max life time of connection

  

默认情况下,Oracle不对连接强制执行最大生存期(在JDBC驱动程序端(1)或服务器端(2)上均不)。因此,在这方面,“基础结构施加的连接时间限制”是+ infinity