浅析mybatis源码(二)连接池

本文深入探讨了MyBatis中PooledDataSource类的实现,解析了数据库连接池的参数设置及其工作原理,包括连接的获取与释放策略,以及状态类PoolState的属性说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇主要看的是mybatis对于数据库连接池的实现。实现类为org.apache.ibatis.datasource.pooled包下的PooledDataSource类。 数据库连接池的代码并不难,关键在于理解他的连接和释放的策略。

连接池参数

  protected int poolMaximumActiveConnections = 10;//最大存活连接数,有请求的连接
  protected int poolMaximumIdleConnections = 5;//最大空闲连接数,就是没有处理请求的连接
  protected int poolMaximumCheckoutTime = 20000;//强制收回时间
  protected int poolTimeToWait = 20000;//获取连接等待时间
  protected int poolMaximumLocalBadConnectionTolerance = 3;//如果获取到的是一个坏的连接,那么重新获取一个新的连接,次数最多为 poolMaximumIdleConnections + poolMaximumLocalBadConnectionTolerance
  protected String poolPingQuery = "NO PING QUERY SET";//心跳查询sql
  protected boolean poolPingEnabled;//允许心跳查询
  protected int poolPingConnectionsNotUsedFor;//执行心跳查询频率

还有一个属性poolState用来存放数据库状态,来看看状态类PoolState的属性

连接池状态类属性

  protected final List<PooledConnection> idleConnections = new ArrayList<PooledConnection>();//空闲连接列表
  protected final List<PooledConnection> activeConnections = new ArrayList<PooledConnection>();//活跃连接列表
  protected long requestCount = 0;//获取到有效连接的次数
  protected long accumulatedRequestTime = 0;//获取到有效连接的总耗时
  protected long accumulatedCheckoutTime = 0;//收回连接的总耗时
  protected long claimedOverdueConnectionCount = 0;//强制获取连接次数
  protected long accumulatedCheckoutTimeOfOverdueConnections = 0;//强制收回连接占用时间之和
  protected long accumulatedWaitTime = 0;//等待连接收回时间之和
  protected long hadToWaitCount = 0;//等待的请求数量
  protected long badConnectionCount = 0;//坏连接数量

连接池最重要的两个方法莫过于获取连接和释放连接。在池中pop和push则需要根据连接池参数来进行决策。而每次动作都会更新响应的状态。接下来看看pop和push的具体策略

pop策略

push策略

由于变量名太长,无法在流程图中标明连接池状态是如何变化的。有兴趣的可以看下源码。看下源码就能对那些状态变量有了更清晰的认识。

PooledConnection类

怎么才能在close的时候不是真的close而是调用pushConnection呢?有一种方式就是使用代理。静态代理相对麻烦,需要把除了close方法外所有方法委托给真实的Connection类。mybatis使用的是动态代理。

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    String methodName = method.getName();
    if (CLOSE.hashCode() == methodName.hashCode() && CLOSE.equals(methodName)) {//若是close方法
      dataSource.pushConnection(this);
      return null;
    } else {
      try {
        if (!Object.class.equals(method.getDeclaringClass())) {//如果不是Object定义的那些方法
          checkConnection();//检查连接是否有效
        }
        return method.invoke(realConnection, args);//其他方法委托给realConnection
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    }
  }

总结

连接池的代码并不难,但是可以给我们一个启发,当使用mybatis连接池遇到问题时或者需要优化、监控等,可以获取到poolState的各个属性,来做一些参考。

转载于:https://my.oschina.net/u/3361610/blog/3009002

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值