// 循环获取连接 while (conn == null) { // 加锁 lock.lock(); try { // 如果闲置的连接列表不为空 if (!state.idleConnections.isEmpty()) { // Pool has available connection // 连接池有可用的连接 conn = state.idleConnections.remove(0); if (log.isDebugEnabled()) { log.debug("Checked out connection " + conn.getRealHashCode() + " from pool."); } } else { // Pool does not have available connection // 进入这个分支表示没有空闲连接,但是活跃连接数还没达到最大活跃连接数上限,那么这时候就可以创建一个新连接 if (state.activeConnections.size() < poolMaximumActiveConnections) { // Can create new connection // 这里创建连接我们之前讲过, conn = newPooledConnection(dataSource.getConnection(), this); if (log.isDebugEnabled()) { log.debug("Created connection " + conn.getRealHashCode() + "."); } } else { // Cannot create new connection // 进到这个分支了就表示没法创建新连接了,那么怎么办呢,这里引入了一个 poolMaximumCheckoutTime,这代表了我去控制连接一次被使用的最长时间,如果超过这个时间了,我就要去关闭失效它 PooledConnectionoldestActiveConnection= state.activeConnections.get(0); longlongestCheckoutTime= oldestActiveConnection.getCheckoutTime(); if (longestCheckoutTime > poolMaximumCheckoutTime) { // Can claim overdue connection // 所有超时连接从池中被借出的次数+1 state.claimedOverdueConnectionCount++; // 所有超时连接从池中被借出并归还的时间总和 + 当前连接借出时间 state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime; // 所有连接从池中被借出并归还的时间总和 + 当前连接借出时间 state.accumulatedCheckoutTime += longestCheckoutTime; // 从活跃连接数中移除此连接 state.activeConnections.remove(oldestActiveConnection); // 如果该连接不是自动提交的,则尝试回滚 if (!oldestActiveConnection.getRealConnection().getAutoCommit()) { try { oldestActiveConnection.getRealConnection().rollback(); } catch (SQLException e) { /* Just log a message for debug and continue to execute the following statement like nothing happened. Wrap the bad connection with a new PooledConnection, this will help to not interrupt current executing thread and give current thread a chance to join the next competition for another valid/good database connection. At the end of this loop, bad {@link @conn} will be set as null. */ 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 { // Must wait // 这样还是获取不到连接就只能等待了 try { // 标记状态,然后把等待计数+1 if (!countedWait) { state.hadToWaitCount++; countedWait = true; } if (log.isDebugEnabled()) { log.debug("Waiting as long as " + poolTimeToWait + " milliseconds for connection."); } longwt= System.currentTimeMillis(); // 等待 poolTimeToWait 时间 condition.await(poolTimeToWait, TimeUnit.MILLISECONDS); // 记录等待时间 state.accumulatedWaitTime += System.currentTimeMillis() - wt; } catch (InterruptedException e) { // set interrupt flag Thread.currentThread().interrupt(); 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."); } // 连接无效,坏连接+1 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."); } } } } finally { // 释放锁 lock.unlock(); }
}
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."); } // fanhui return conn; }