温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java mybatis为何连接池耗尽

发布时间:2026-09-02 18:31:17 来源:亿速云 阅读:83 作者:小樊 栏目:编程语言

在 Java + MyBatis 项目中,**连接池耗尽(Connection Pool Exhausted)**是一个非常常见的问题。本质上原因是:连接被借出后,没有被及时归还,导致连接池里可用连接数为 0,后续请求只能等待或报错。

下面从「常见原因 → 排查思路 → 解决方案」详细说明。


一、最常见的原因

1️⃣ SQL 执行后未关闭资源(最常见)

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();
}

2️⃣ 事务未提交 / 未回滚

如果开启了事务但一直不结束:

@Transactional
public void test() {
    mapper.update();
    // 死循环或异常未抛出
}

连接会一直被事务占用,直到超时。

✅ 确保:

  • 方法正常结束
  • 异常能正确抛出
  • 没有长事务

3️⃣ 慢 SQL 占用连接

一条 SQL 执行 10 秒,连接池只有 10 个 → 10 秒后全满。

常见场景:

  • 全表扫描
  • 缺少索引
  • 联表过多
  • LIMIT 缺失

✅ 排查:

SHOW PROCESSLIST;

4️⃣ 连接泄漏(框架/代码 bug)

典型情况:

  • 自己手动拿 Connection
  • 使用 DataSourceUtils.getConnection() 未释放
  • 多线程中错误共享 SqlSession

5️⃣ 连接池配置过小

spring:
  datasource:
    hikari:
      maximum-pool-size: 10

高并发下 10 个连接根本不够。

✅ 根据 QPS 和 SQL 耗时估算:

连接数 ≈ QPS × 平均SQL耗时(s)

6️⃣ 连接未回收(网络/数据库异常)

  • 数据库宕机
  • 网络中断
  • 防火墙断开空闲连接

✅ 需要配置:

  • 连接存活检测
  • 超时回收

二、不同连接池的典型问题

HikariCP(Spring Boot 默认)

常见错误:

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

Druid

开启监控:

spring:
  datasource:
    druid:
      filters: stat,wall

查看:

/druid/index.html

三、快速排查步骤(实战)

✅ 1. 看异常

Timeout: Pool empty
Cannot get connection
Connection pool exhausted

✅ 2. 看连接池监控

  • Hikari:日志
  • Druid:Web 页面

✅ 3. 看数据库

SHOW PROCESSLIST;

✅ 4. 看代码

  • @Transactional 是否过大
  • SqlSession 是否关闭
  • 是否有循环调用 DAO

四、最佳实践(防坑)

✅ 使用 Spring + MyBatis(自动管理)

@Mapper
public interface UserMapper {
    User selectById(Long id);
}

✅ 避免长事务
✅ SQL 必须走索引
✅ 连接池大小合理
✅ 开启连接存活检测


五、一句话总结

MyBatis 连接池耗尽,99% 是因为“借了连接没还”或“还得太慢”。

如果你愿意,可以把:

  • 使用的连接池(Hikari / Druid)
  • 报错日志
  • 相关代码

发出来,我可以帮你精确定位是哪一行代码导致泄漏

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI