Spring Boot项目MySQL Too many connections问题求助(已调大连接数)
解决Spring Boot + MySQL连接耗尽(Too many connections)问题
问题背景
团队开发Spring Boot项目时,多人共用同一MySQL数据库,运行一段时间后部分成员无法连接,报错Too many connections。已联系DBA将数据库最大连接数从150调整至500,但问题仍未解决。当前仅配置以下数据源属性:
spring.datasource.url= ... spring.datasource.username= ... spring.datasource.password= ... spring.datasource.hikari.maximum-pool-size=25
怀疑JPA每次查询新建连接未关闭,但无从排查。
补充代码如下:
业务层实现代码
@Autowired private EmployeeDAO employeeDAO; @Autowired private LogDAO logDAO; @Autowired private ContrattoLavoroDAO contrattoLavoroDAO; @Override public void deleteEmployeeById(Long idEmployee, String username) { contrattoLavoroDAO.deleteContrattoByEmpId(idEmployee); employeeDAO.deleteById(idEmployee); LogEntity log = new LogEntity(); LocalDateTime date = LocalDateTime.now(); log.setData(date); log.setUser(username); log.setCrud("delete"); log.setTabella("Employees"); log.setDescrizione("l'utente " + username + " ha rimosso il dipendente con matricola " + idEmployee); logDAO.save(log); }
DAO层示例代码
public interface ContrattoLavoroDAO extends JpaRepository<ContrattoLavoroEntity, Long> { @Modifying @Query(value = "DELETE contratto_lavoro, employee_contratto FROM contratto_lavoro" + " INNER JOIN" + " employee_contratto ON employee_contratto.id_contratto = contratto_lavoro.id_contratto" + " WHERE" + " contratto_lavoro.id_contratto = ?1", nativeQuery = true) public void deleteContrattoByEmpId(Long empId); }
排查与解决思路
1. 先定位连接占用的真实情况
先通过MySQL命令查看当前连接状态,别直接定性为JPA的问题:
-- 查看所有当前连接的状态、来源、用户 SHOW PROCESSLIST; -- 查看当前总连接数 SHOW STATUS LIKE 'Threads_connected';
重点关注Sleep状态的连接、连接来源IP(区分开发机器)、对应的数据库用户,快速定位是哪个实例在占用过多连接。
2. 修复@Modifying注解的事务缺失问题
你的deleteContrattoByEmpId方法使用了@Modifying执行原生删除SQL,但没有事务上下文,这是常见的连接泄漏点:JPA执行@Modifying操作时,若无事务管理,连接可能无法正常回收到Hikari连接池。
解决方法:在业务方法上添加@Transactional注解(推荐业务层统一管理事务):
@Override @Transactional public void deleteEmployeeById(Long idEmployee, String username) { // 原有代码保持不变 }
3. 完善HikariCP连接池配置
当前仅设置了maximum-pool-size=25,补充关键参数让连接池更主动地管理连接:
# 最小空闲连接数,维持池内基础可用连接 spring.datasource.hikari.minimum-idle=5 # 连接超时时间,防止连接等待过久 spring.datasource.hikari.connection-timeout=30000 # 连接最大存活时间,定期回收旧连接 spring.datasource.hikari.max-lifetime=1800000 # 空闲连接超时时间,自动回收闲置过久的连接 spring.datasource.hikari.idle-timeout=600000
4. 控制开发环境的连接占用
多人开发时,每个本地应用实例都会创建独立的连接池:按当前maximum-pool-size=25计算,10个开发者就会占用250个连接,再加上其他服务的连接,很容易触达500的上限。
建议:
- 将本地实例的
maximum-pool-size下调至10以内,减少单实例连接占用。 - 提醒开发者关闭闲置的应用实例,避免无用连接长期占用资源。
5. 监控连接池状态验证修复效果
通过Spring Boot Actuator监控Hikari连接池状态,确认连接是否正常释放:
- 添加Actuator依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
- 配置暴露连接池指标:
management.endpoints.web.exposure.include=hikaricp
- 访问
/actuator/hikaricp查看活跃连接数、空闲连接数等指标,验证连接是否被正常回收。
内容的提问来源于stack exchange,提问作者santocielo99
相关产品推荐
相关产品推荐

