弹簧启动请求开始时,它将从池中获得连接。我的问题是-此连接是否仍与请求线程保持联系(即使它没有执行任何查询),并且仅在请求完成时才返回到池中?
例如,如果我正在做类似的事情:
此请求线程获得的连接是否会在20ms或1520ms内被该线程占用(对其他请求不可用)?
PS:我正在将Spring Boot 2.0与HikariCP一起使用,而没有使用@Transactional。
谢谢。
答案 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