CommonDataSource数据池的定义是在jdk库中,是对数据源概念的抽象顶层,指定了数据源必须实现的方法。
概述一下其链接的过程如下图:
使用线程池可以减少频繁创建、销毁线程带来的性能损害。通过配置各种参数保证系统在实际的应用中有更好的负载和性能之间获得更好的实践。
Mybatis提供了一个简单的连接池,主要分析一下这个class:org.apache.ibatis.datasource.pooled.PooledDataSource
protected int poolMaximumActiveConnections = 10; //激活线程池最大数
protected int poolMaximumIdleConnections = 5; //空闲线程池最大数
protected int poolMaximumCheckoutTime = 20000; //最长的保持链接时间
protected int poolTimeToWait = 20000; //没有可用conn的时候,等待时间
protected int poolMaximumLocalBadConnectionTolerance = 3;//有多少个badConn最大数
基础控制线程池的参数、连接表都在这里来维护;
protected long requestCount = 0; //conn被使用次数,请求次数
protected long accumulatedRequestTime = 0; //累计签发线程所需的时间
protected long accumulatedCheckoutTime = 0; //累计conn链接时间
protected long claimedOverdueConnectionCount = 0; //回收超期conn的次数
protected long accumulatedCheckoutTimeOfOverdueConnections = 0; //超期线程累计使用多长时间
protected long accumulatedWaitTime = 0; //等待签发conn累计等候时间
protected long hadToWaitCount = 0; //无有效的conn,需要等候的次数
protected long badConnectionCount = 0; //bad链接数
1)取出:在需要数据链接的时候会请求connection,调用popConnection;
2)归还:在处理完之后需要将conn归还线程池,调用pushConnection
1)问:为什么所有的线程都要判断是不是AutoCommit,并要RollBack?
在JDBC通过Connection管理事务的,默认会自动提交事务。也可以手工关闭,同构commit方法提交,通过rollBack进行回滚。
所以,每次释放连接的时候都要判断如果自动提交被关闭了,则后续断开的时候需要RollBack。
rollBack一般会判断是否已经关闭连接,如果连接还没有close,则会撤销事务内所有的变更,并释放数据库锁。
2)问:为啥旧的连接,要设置为无效,重新包装一个newPoolConnection?
因为PoolConnection是在实际的连接基础上重新加上了线程池所需要的属性,比如
private final int hashCode;
private final PooledDataSource dataSource; //连接池属性
private final Connection realConnection; //实际连接
private final Connection proxyConnection;
private long checkoutTimestamp; //保持连接的时间
private long createdTimestamp; //创建时间
private long lastUsedTimestamp; //最有一次使用时间
private int connectionTypeCode; //连接类型编码
private boolean valid; //状态标识(新建时为true)
3)问:invalidate具体是怎么样的?被设置为invalidate的线程最后哪里去了
invalidate会将PoolConnection的属性valid设置为false,后续不会被用于任何地方, 垃圾回收将其回收掉。
4)问:如何判断连接时isValidate()
判断3个条件,
5)问:conn要设置ConnectionTypeCode,这个作用什么?
conn.setConnectionTypeCode(assembleConnectionTypeCode(dataSource.getUrl(), username, password));
这个适用于生成这个连接的HashCode(poolConnection的属性)来标识每个连接的的唯一性