在 Java + MyBatis 项目中,**连接池耗尽(Connection Pool Exhausted)**是一个非常常见的问题。本质上原因是:连接被借出后,没有被及时归还,导致连接池里可用连接数为 0,后续请求只能等待或报错。
下面从「常见原因 → 排查思路 → 解决方案」详细说明。
MyBatis 底层依赖 JDBC,SqlSession / Connection 必须关闭。
错误示例(Spring 外使用 MyBatis):
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.selectUser();
// 忘记 session.close()
✅ 正确方式:
try (SqlSession session = sqlSessionFactory.openSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.selectUser();
}
如果开启了事务但一直不结束:
@Transactional
public void test() {
mapper.update();
// 死循环或异常未抛出
}
连接会一直被事务占用,直到超时。
✅ 确保:
一条 SQL 执行 10 秒,连接池只有 10 个 → 10 秒后全满。
常见场景:
LIMIT 缺失✅ 排查:
SHOW PROCESSLIST;
典型情况:
ConnectionDataSourceUtils.getConnection() 未释放SqlSessionspring:
datasource:
hikari:
maximum-pool-size: 10
高并发下 10 个连接根本不够。
✅ 根据 QPS 和 SQL 耗时估算:
连接数 ≈ QPS × 平均SQL耗时(s)
✅ 需要配置:
常见错误:
HikariPool-1 - Connection is not available, request timed out
配置建议:
spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
开启监控:
spring:
datasource:
druid:
filters: stat,wall
查看:
/druid/index.html
Timeout: Pool empty
Cannot get connection
Connection pool exhausted
SHOW PROCESSLIST;
@Transactional 是否过大SqlSession 是否关闭✅ 使用 Spring + MyBatis(自动管理)
@Mapper
public interface UserMapper {
User selectById(Long id);
}
✅ 避免长事务
✅ SQL 必须走索引
✅ 连接池大小合理
✅ 开启连接存活检测
MyBatis 连接池耗尽,99% 是因为“借了连接没还”或“还得太慢”。
如果你愿意,可以把:
发出来,我可以帮你精确定位是哪一行代码导致泄漏。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。