如何判断Spring Boot服务是否占用数据库连接?
嘿,针对你的场景(Spring Boot+Hibernate+Spring Data JPA,服务层用@Transactional,部分方法不需要事务也不想占用连接),我给你整理了几个靠谱的方法,帮你准确判断方法是否在占用数据库连接:
借助Spring Boot Actuator监控连接池状态
这是最直观的监控方式。先给项目加上Actuator依赖,然后在配置文件里开启metrics端点。如果用的是默认的HikariCP连接池,启动应用后访问/actuator/metrics/hikaricp.connections.active就能看到当前活跃的数据库连接数。
你可以做个小测试:调用目标方法前记录下活跃连接数,方法执行完再看一次。如果数值没变化,说明这个方法没占用连接;要是涨了,那肯定是有连接被占用了。另外还能看/actuator/metrics/hikaricp.connections.idle这类指标,对比空闲连接数的变化,结果更准确。配置连接池日志,追踪连接的生命周期
直接让连接池把连接的获取、释放过程打出来,一眼就能看明白。比如HikariCP的话,在application.properties里加一行:logging.level.com.zaxxer.hikari=DEBUG这样日志里会清晰打印类似「Acquired connection HikariProxyConnection@xxxx from pool」和「Released connection HikariProxyConnection@xxxx back to pool」的信息。你调用那些不需要事务的方法时,如果日志里没出现获取连接的记录,就说明它没碰连接池;反之就要检查你的事务注解是不是没配置对。
代码层面直接验证连接状态
如果你想在代码里直接确认,用Spring提供的TransactionSynchronizationManager工具类就行。在目标方法里加几行代码:import org.springframework.transaction.support.TransactionSynchronizationManager; import javax.sql.DataSource; // 注入你的数据源 @Autowired private DataSource dataSource; public void nonTransactionalMethod() { // 判断是否有活跃事务 boolean hasActiveTx = TransactionSynchronizationManager.isActualTransactionActive(); // 判断是否持有数据库连接 boolean hasConnection = TransactionSynchronizationManager.hasResource(dataSource); System.out.println("当前是否有活跃事务:" + hasActiveTx); System.out.println("当前是否占用数据库连接:" + hasConnection); }如果两个结果都是
false,说明这个方法完全没占用连接。这里要提醒你:如果你的类上标注了@Transactional(readOnly = true),那类里所有方法默认都会继承这个事务注解!这时候你必须在不需要事务的方法上显式标注@Transactional(propagation = Propagation.NOT_SUPPORTED),强制它在无事务环境下运行,才不会占用连接。
备注:内容来源于stack exchange,提问作者Kevin

