SpringBoot中Hibernate多线程执行受限问题求助
SpringBoot+Hibernate多线程调用API时,仅10个线程能并行执行查询后步骤
问题描述
在SpringBoot应用中搭配Hibernate使用,多线程调用某个API时遇到并发瓶颈:调用Hibernate的findBy()方法后,只有10个线程能立即执行到Step 1,剩下的线程必须等这10个线程走完整个流程释放资源后,才能继续执行Step 1。
启动20个线程测试时,所有线程同时到达Step 0,但Step 1的执行明显分批——前10个线程完成响应后,剩下的线程才陆续进入Step 1。
相关代码
System.out.println("Step 0 - " + System.currentTimeMillis()); Optional<RuleMaster> master = ruleMasterDao.findByRuleId(id); System.out.println("Step 1 - " + System.currentTimeMillis());
控制台输出
测试时控制台输出片段:
Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 0 :1689945805814 Step - 0 :1689945805814 Step - 0 :1689945805813 Step - 0 :1689945805815 Step - 0 :1689945805814 Step - 0 :1689945805814 Step - 0 :1689945805814 Step - 0 :1689945805814 Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 0 :1689945805813 Step - 1 :1689945805868 Step - 1 :1689945805868 Step - 1 :1689945805868 Step - 1 :1689945805868 Step - 1 :1689945805868 Step - 1 :1689945805869 Step - 1 :1689945805869 Step - 1 :1689945805868 Step - 1 :1689945805869 Step - 1 :1689945805869 Final Response At : 1689945810355 Final Response At : 1689945810355 Step - 1 :1689945810402 Step - 1 :1689945810402 Final Response At : 1689945810564 Step - 1 :1689945810574 Final Response At : 1689945810675 Step - 1 :1689945810690 Final Response At : 1689945810706 Step - 1 :1689945810722 Final Response At : 1689945810722 Final Response At : 1689945810722 Step - 1 :1689945810731 Step - 1 :1689945810738 Final Response At : 1689945810738 Step - 1 :1689945810754 Final Response At : 1689945810770 Step - 1 :1689945810770 Final Response At : 1689945810793 Step - 1 :1689945810793 Final Response At : 1689945814180 Final Response At : 1689945814243 Final Response At : 1689945814337 Final Response At : 1689945814352 Final Response At : 1689945814449 Final Response At : 1689945814463 Final Response At : 1689945814574 Final Response At : 1689945814668 Final Response At : 1689945814715 Final Response At : 1689945814746
问题原因
这是数据库连接池的并发限制导致的。Spring Boot默认使用HikariCP连接池,其默认最大连接数为10——刚好和你观察到的并发线程数一致。当10个连接被全部占用时,后续线程必须等待已有连接释放,才能获取连接执行Hibernate查询,进而进入Step 1。
解决方法
1. 调整数据库连接池大小
在配置文件中修改HikariCP的最大连接数,匹配你的并发需求:
- application.properties格式:
# 设置最大连接数,根据并发量调整,比如设为20 spring.datasource.hikari.maximum-pool-size=20 # 设置最小空闲连接数,维持基础连接池规模 spring.datasource.hikari.minimum-idle=10 - application.yml格式:
spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 10
注意:不要盲目设置过大的连接数,否则会增加数据库的负载压力,反而影响性能。
2. 确保Hibernate会话的线程安全性
Spring中SessionFactory是线程安全的,而Session是非线程安全的。如果DAO层使用了@Transactional注解,Spring会自动为每个线程分配独立的Session,这本身没有问题,但连接池不够时依然会等待,所以核心还是调整连接池大小。
3. 优化查询性能
如果findByRuleId查询本身耗时较长,即使增大连接池也可能出现瓶颈,可以从以下方面优化:
- 给
rule_id字段添加数据库索引,加速查询 - 优化HQL/JPQL语句,避免不必要的关联查询或字段加载
- 引入缓存机制,比如使用Spring Cache或Hibernate二级缓存,缓存查询结果,减少数据库访问次数
内容的提问来源于stack exchange,提问作者Parth Atara
相关产品推荐
相关产品推荐

