mybatis 连接池的实现原理
介绍了概念和使用。最后,让我们看看 mybatis 如何实现连接池?首先看代码
mybatis 这个包下面有与连接池相关的代码。从这里可以看出,有三种实现:jndi、pooled、unpooled,配置符合官方介绍。同时也可以看出,它使用工厂模式来创建数据源。jndi 不做具体的介绍,可能是通过配置文件配置,然后在代码中根据具体的数据源对象的名称使用,tomcat就是这样做的,参考JNDI介绍。主要来看下 pooled 顺便说一句,你也会明白方法 unpooled 方式。
在介绍原始使用方法时,通过配置 type 成 POOLED,我们可以使用池数据源,首先是因为 mybatis 内置相应的假名和具体的映射实现类
这样就可以找到具体的实现类别PooledDataSourceFactory,看具体代码
可见继承UnpooledDataSourceFactory,主要用于赋值配置的属性
另一个是生成一个PooledDataSource。这是池化数据源的对象,我在这里加注释,方便理解
其中一个可以看到UnpooledDataSource该类型的变量负责创建新的连接。
所有用户名、密码等属性都在这里,包括数据库驱动包。说白了,这个类别是配置数据库信息,获取新的连接。回头看PooledDataSource,当我们去获取连接时,它会一次进行 pop 操作
这个pop操作是线程安全的,因为使用了锁,锁的对象是PoolState,PoolState它是整个池下唯一的一个。它用于管理连接池信息。管理哪些信息?
这是非常清楚的,有了它PoolState,我们可以更好地了解连接池的使用情况。再回头看PooledDataSource的 popConnection 方法
这里分解的逻辑如下:
1、存在空闲连接时,直接检出;
2、如果没有空闲连接,首先判断活动连接是否达到最大活动数
1)否则,新建连接
2)是的,取出最早检出的活跃连接,判断检出时间是否大于最大逾期时间是的,声明连接失效并建立新的连接 否则,等待配置的等待时间(2s)
3、如果连接被取回,将进行一次统计并返回。如果不能取回,将再次循环获取
再来看一下 pushConnection 方法
顾名思义,pop是取出连接,push是放回连接和pop使用的锁,线程也是安全的。什么时候触发连接放回操作?看看这个类别PooledConnection
我在这里也加了注释。这类产品的功能可能是代理真实连接,整个代理操作是将close操作放回连接到连接池
在每次 pop 和 push 连接时会检测连接的有效性,此时使用 pingConnection 方法
这种方法也相对简单,即在周期到来时,将检测连接的有效性。