入口-BasicDataSource
执行sql的时候,就会先获取数据库连接,在哪里获取?就在这里。
/**
* Create (if necessary) and return a connection to the database.
*
* @throws SQLException if a database access error occurs
* @return a database connection
*/
public Connection getConnection() throws SQLException {
return createDataSource().getConnection();
}
获取连接的核心类
核心步骤
1.从连接池获取连接对象
2.校验连接是否有效
源码
GenericObjectPool
public T borrowObject() throws Exception {
long starttime = System.currentTimeMillis();
GenericObjectPool.Latch<T> latch = new GenericObjectPool.Latch();
byte whenExhaustedAction;
long maxWait;
//排队处理
synchronized(this) {
whenExhaustedAction = this._whenExhaustedAction;
maxWait = this._maxWait;
this._allocationQueue.add(latch);
}
//从连接池获取连接
this.allocate();
while(true) {
synchronized(this) {
this.assertOpen();
}
if (latch.getPair() == null && !latch.mayCreate()) {
switch(whenExhaustedAction) {
case 0:
synchronized(this) {
if (latch.getPair() == null && !latch.mayCreate()) {
this._allocationQueue.remove(latch);
throw new NoSuchElementException("Pool exhausted");
}
break;
}
case 1:
try {
synchronized(latch) {
if (latch.getPair() != null || latch.mayCreate()) {
break;
}
if (maxWait <= 0L) {
latch.wait();
} else {
long elapsed = System.currentTimeMillis() - starttime;
long waitTime = maxWait - elapsed;
if (waitTime > 0L) {
latch.wait(waitTime);
}
}
}
if (this.isClosed()) {
throw new IllegalStateException("Pool closed");
}
} catch (InterruptedException var51) {
boolean doAllocate = false;
synchronized(this) {
if (latch.getPair() == null && !latch.mayCreate()) {
this._allocationQueue.remove(latch);
} else if (latch.getPair() == null && latch.mayCreate()) {
--this._numInternalProcessing;
doAllocate = true;
} else {
--this._numInternalProcessing;
++this._numActive;
this.returnObject(latch.getPair().getValue());
}
}
if (doAllocate) {
this.allocate();
}
Thread.currentThread().interrupt();
throw var51;
}
if (maxWait <= 0L || System.currentTimeMillis() - starttime < maxWait) {
continue;
}
synchronized(this) {
if (latch.getPair() != null || latch.mayCreate()) {
break;
}
this._allocationQueue.remove(latch);
}
throw new NoSuchElementException("Timeout waiting for idle object");
case 2:
synchronized(this) {
if (latch.getPair() == null && !latch.mayCreate()) {
this._allocationQueue.remove(latch);
++this._numInternalProcessing;
}
break;
}
default:
throw new IllegalArgumentException("WhenExhaustedAction property " + whenExhaustedAction + " not recognized.");
}
}
boolean newlyCreated = false;
if (null == latch.getPair()) {
boolean var36 = false;
try {
var36 = true;
T obj = this._factory.makeObject();
latch.setPair(new ObjectTimestampPair(obj));
newlyCreated = true;
var36 = false;
} finally {
if (var36) {
if (!newlyCreated) {
synchronized(this) {
--this._numInternalProcessing;
}
this.allocate();
}
}
}
if (!newlyCreated) {
synchronized(this) {
--this._numInternalProcessing;
}
this.allocate();
}
}
try {
this._factory.activateObject(latch.getPair().value); //
if (this._testOnBorrow//每次获取连接是否校验有效,默认值是false && !this._factory.validateObject(latch.getPair().value)) { //这里不会校验,因为_testOnBorrow=false
throw new Exception("ValidateObject failed");
}
synchronized(this) {
--this._numInternalProcessing; //内部进程数量加1
++this._numActive; //当前活跃数量加1
}
return latch.getPair().value; //返回连接对象
} catch (Throwable var47) {
PoolUtils.checkRethrow(var47);
try {
this._factory.destroyObject(latch.getPair().value);
} catch (Throwable var42) {
PoolUtils.checkRethrow(var42);
}
synchronized(this) {
--this._numInternalProcessing;
if (!newlyCreated) {
latch.reset();
this._allocationQueue.add(0, latch);
}
}
this.allocate();
if (newlyCreated) {
throw new NoSuchElementException("Could not create a validated object, cause: " + var47.getMessage());
}
}
}
}
PoolableConnectionFactory
激活连接对象,为什么要激活?因为连接池在实际项目当中都是关闭自动提交,即
1.开始事务 //一开始是关闭自动提交的
2.sql1
3.sql2
4.提交事务 //最后提交事务的时候,才会设置为自动提交
protected boolean _defaultAutoCommit = true; //连接池默认是自动提交
public void activateObject(Object obj) throws Exception {
if (obj instanceof DelegatingConnection) {
((DelegatingConnection)obj).activate();
}
if (obj instanceof Connection) {
Connection conn = (Connection)obj;
if (conn.getAutoCommit()//项目里禁用自动提交,所以值是false != this._defaultAutoCommit//连连接池默认是自动提交,所以值是true) {
conn.setAutoCommit(this._defaultAutoCommit); //为什么要设置为自动提交?提交事务的时候,会设置为自动提交
}
if (this._defaultTransactionIsolation != -1 && conn.getTransactionIsolation() != this._defaultTransactionIsolation) {
conn.setTransactionIsolation(this._defaultTransactionIsolation);
}
if (this._defaultReadOnly != null && conn.isReadOnly() != this._defaultReadOnly) {
conn.setReadOnly(this._defaultReadOnly);
}
if (this._defaultCatalog != null && !this._defaultCatalog.equals(conn.getCatalog())) {
conn.setCatalog(this._defaultCatalog);
}
}
}
从连接池获取连接对象
真正获取连接对象的是这个方法
private CursorableLinkedList<ObjectTimestampPair<T>> _pool; //连接池,是一个LinkedList
//从连接池获取连接
private synchronized void allocate() {
if (!this.isClosed()) {
GenericObjectPool.Latch latch; //封装了连接对象
while(!this._pool.isEmpty() && !this._allocationQueue.isEmpty()) {
latch = (GenericObjectPool.Latch)this._allocationQueue.removeFirst(); //从排队里获取一个进行处理
latch.setPair((ObjectTimestampPair)this._pool.removeFirst()); //从连接池获取连接对象
++this._numInternalProcessing;
synchronized(latch) {
latch.notify();
}
}
while(!this._allocationQueue.isEmpty() && (this._maxActive < 0 || this._numActive + this._numInternalProcessing < this._maxActive)) {
latch = (GenericObjectPool.Latch)this._allocationQueue.removeFirst();
latch.setMayCreate(true);
++this._numInternalProcessing;
synchronized(latch) {
latch.notify();
}
}
}
}
校验连接是否有效
public boolean validateObject(Object obj) {
if (obj instanceof Connection) {
try {
this.validateConnection((Connection)obj); //校验连接是否有效
return true; //如果连接有效,就返回true
} catch (Exception var3) {
return false; //如果连接无效,就返回false
}
} else {
return false;
}
}
public void validateConnection(Connection conn) throws SQLException {
String query = this._validationQuery;
if (conn.isClosed()) { //连接已经关闭
throw new SQLException("validateConnection: connection closed");
} else { //连接没有关闭,就校验连接是否有效:通过查询数据库,来校验连接是否有效
if (null != query) {
Statement stmt = null;
ResultSet rset = null;
try {
stmt = conn.createStatement();
if (this._validationQueryTimeout > 0) {
stmt.setQueryTimeout(this._validationQueryTimeout);
}
rset = stmt.executeQuery(query);
if (!rset.next()) {
throw new SQLException("validationQuery didn't return a row");
}
} finally {
if (rset != null) {
try {
rset.close();
} catch (Exception var14) {
}
}
if (stmt != null) {
try {
stmt.close();
} catch (Exception var13) {
}
}
}
}
}
}
数据结构
连接对象
封装了连接对象
private static final class Latch<T> {
private ObjectTimestampPair<T> _pair;
static class ObjectTimestampPair<T> implements Comparable<T> {
/** @deprecated */
@Deprecated
T value; //连接对象
/** @deprecated */
@Deprecated
long tstamp;
连接池
private CursorableLinkedList<ObjectTimestampPair<T>> _pool; //是一个集合,元素是连接对象
性能
获取连接的时候,有锁
private synchronized void allocate() { //同步方法
if (!this.isClosed()) {
GenericObjectPool.Latch latch;
while(!this._pool.isEmpty() && !this._allocationQueue.isEmpty()) {
latch = (GenericObjectPool.Latch)this._allocationQueue.removeFirst();
latch.setPair((ObjectTimestampPair)this._pool.removeFirst());
++this._numInternalProcessing;
synchronized(latch) {
latch.notify();
}
}
while(!this._allocationQueue.isEmpty() && (this._maxActive < 0 || this._numActive + this._numInternalProcessing < this._maxActive)) {
latch = (GenericObjectPool.Latch)this._allocationQueue.removeFirst();
latch.setMayCreate(true);
++this._numInternalProcessing;
synchronized(latch) {
latch.notify();
}
}
}
}
截图
1、获取连接对象
真正获取连接对象的方法
2、校验连接是否有效
dbcp和pool
dbcp是基于pool,底层的连接池都是pool实现的。
调用栈
borrowObject:1059, GenericObjectPool (org.apache.commons.pool.impl) //从连接池获取连接对象
getConnection:106, PoolingDataSource (org.apache.commons.dbcp) //获取连接
getConnection:1044, BasicDataSource (org.apache.commons.dbcp) //获取连接
getConnection:26, DbcpSecretBasicDataSource (xxx.qrcode.common.monitor.dbcp) //获取连接
getConnection:83, LocalDataSourceConnectionProvider (org.springframework.orm.hibernate3)
openConnection:446, ConnectionManager (org.hibernate.jdbc)
getConnection:167, ConnectionManager (org.hibernate.jdbc)
connection:160, JDBCContext (org.hibernate.jdbc)
begin:81, JDBCTransaction (org.hibernate.transaction)
beginTransaction:1473, SessionImpl (org.hibernate.impl)
doBegin:556, HibernateTransactionManager (org.springframework.orm.hibernate3) //开始事务
getTransaction:372, AbstractPlatformTransactionManager (org.springframework.transaction.support) //获取事务
createTransactionIfNecessary:417, TransactionAspectSupport (org.springframework.transaction.interceptor)
invokeWithinTransaction:255, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:94, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:172, ReflectiveMethodInvocation (org.springframework.aop.framework)
invoke:91, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:172, ReflectiveMethodInvocation (org.springframework.aop.framework)
intercept:631, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
merModifyNoAudit:-1, UrmtminfService$$EnhancerByCGLIB$$c1377819 (xxx.qrcode.register.dbservice.impl)
merModifyNoAudit:517, QrcodeRegisterServer (xxx.qrcode.register.remoteserver.impl)
invokeMethod:-1, Wrapper22 (com.alibaba.dubbo.common.bytecode)
doInvoke:47, JavassistProxyFactory$1 (com.alibaba.dubbo.rpc.proxy.javassist)
invoke:76, AbstractProxyInvoker (com.alibaba.dubbo.rpc.proxy)
invoke:52, DelegateProviderMetaDataInvoker (com.alibaba.dubbo.config.invoker)
invoke:56, InvokerWrapper (com.alibaba.dubbo.rpc.protocol)
invoke:62, ExceptionFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:75, MonitorFilter (com.alibaba.dubbo.monitor.support)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:42, TimeoutFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:11, AppNameAppendFilter (com.xxx.log.rpc.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:78, TraceFilter (com.alibaba.dubbo.rpc.protocol.dubbo.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:60, ExecuteLimitFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:85, AccessLogExtFilter (xxx.qrcode.common.filter.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:82, CatTransaction (com.xxx.log.rpc.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:73, ContextFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:138, GenericFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:38, ClassLoaderFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:38, EchoFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
reply:104, DubboProtocol$1 (com.alibaba.dubbo.rpc.protocol.dubbo)
handleRequest:96, HeaderExchangeHandler (com.alibaba.dubbo.remoting.exchange.support.header)
received:173, HeaderExchangeHandler (com.alibaba.dubbo.remoting.exchange.support.header)
received:51, DecodeHandler (com.alibaba.dubbo.remoting.transport)
run:57, ChannelEventRunnable (com.alibaba.dubbo.remoting.transport.dispatcher)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)