protected final List<PooledConnection> idleConnections = new ArrayList<PooledConnection>(); protected final List<PooledConnection> activeConnections = new ArrayList<PooledConnection>(); }
while (conn == null) { synchronized (state) {// 给state对象加锁 if (!state.idleConnections.isEmpty()) {// 如果空闲列表不空,就从空闲列表中拿connection // Pool has available connection conn = state.idleConnections.remove(0);// 拿出空闲列表中的第一个,去验证连接是否还有效 if (log.isDebugEnabled()) { log.debug("Checked out connection " + conn.getRealHashCode() + " from pool."); } } else { // 空闲连接池中没有可用的连接,就来看看活跃连接列表中是否有,先判断活动连接总数 是否小于 最大可用的活动连接数 if (state.activeConnections.size() < poolMaximumActiveConnections) { // 如果连接数小于list.size 直接创建新的连接。 conn = newPooledConnection(dataSource.getConnection(), this); if (log.isDebugEnabled()) { log.debug("Created connection " + conn.getRealHashCode() + "."); } } else { // 此时连接数也满了,不能创建新的连接。找到最老的那个,检查它是否过期 // 计算它的校验时间,如果校验时间大于连接池规定的最大校验时间,则认为它已经过期了 // 利用这个PoolConnection内部的realConnection重新生成一个PooledConnection PooledConnectionoldestActiveConnection= state.activeConnections.get(0); longlongestCheckoutTime= oldestActiveConnection.getCheckoutTime(); if (longestCheckoutTime > poolMaximumCheckoutTime) { // 可以要求过期这个连接。 state.claimedOverdueConnectionCount++; state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime; state.accumulatedCheckoutTime += longestCheckoutTime; state.activeConnections.remove(oldestActiveConnection); if (!oldestActiveConnection.getRealConnection().getAutoCommit()) { try { oldestActiveConnection.getRealConnection().rollback(); } catch (SQLException e) { log.debug("Bad connection. Could not roll back"); } } conn = newPooledConnection(oldestActiveConnection.getRealConnection(), this); conn.setCreatedTimestamp(oldestActiveConnection.getCreatedTimestamp()); conn.setLastUsedTimestamp(oldestActiveConnection.getLastUsedTimestamp()); oldestActiveConnection.invalidate(); if (log.isDebugEnabled()) { log.debug("Claimed overdue connection " + conn.getRealHashCode() + "."); } } else { // 如果不能释放,则必须等待 try { if (!countedWait) { state.hadToWaitCount++; countedWait = true; } if (log.isDebugEnabled()) { log.debug("Waiting as long as " + poolTimeToWait + " milliseconds for connection."); } longwt= System.currentTimeMillis(); state.wait(poolTimeToWait); state.accumulatedWaitTime += System.currentTimeMillis() - wt; } catch (InterruptedException e) { break; } } } } if (conn != null) { // ping to server and check the connection is valid or not if (conn.isValid()) {// 去验证连接是否还有效。 if (!conn.getRealConnection().getAutoCommit()) { conn.getRealConnection().rollback(); } conn.setConnectionTypeCode(assembleConnectionTypeCode(dataSource.getUrl(), username, password)); conn.setCheckoutTimestamp(System.currentTimeMillis()); conn.setLastUsedTimestamp(System.currentTimeMillis()); state.activeConnections.add(conn); state.requestCount++; state.accumulatedRequestTime += System.currentTimeMillis() - t; } else { if (log.isDebugEnabled()) { log.debug("A bad connection (" + conn.getRealHashCode() + ") was returned from the pool, getting another connection."); } state.badConnectionCount++; localBadConnectionCount++; conn = null; if (localBadConnectionCount > (poolMaximumIdleConnections + poolMaximumLocalBadConnectionTolerance)) { if (log.isDebugEnabled()) { log.debug("PooledDataSource: Could not get a good connection to the database."); } thrownewSQLException("PooledDataSource: Could not get a good connection to the database."); } } } }
}
if (conn == null) { if (log.isDebugEnabled()) { log.debug("PooledDataSource: Unknown severe error condition. The connection pool returned a null connection."); } thrownewSQLException("PooledDataSource: Unknown severe error condition. The connection pool returned a null connection."); }