public PooledDataSource( ClassLoader driverClassLoader, String driver, String url, Properties driverProperties) { dataSource = new UnpooledDataSource(driverClassLoader, driver, url, driverProperties); expectedConnectionTypeCode = assembleConnectionTypeCode( dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword()); }
public static UnpooledDataSource createUnpooledDataSource(String resource) throws IOException { Properties props = Resources.getResourceAsProperties(resource); UnpooledDataSource ds = new UnpooledDataSource(); ds.setDriver(props.getProperty("driver")); ds.setUrl(props.getProperty("url")); ds.setUsername(props.getProperty("username")); ds.setPassword(props.getProperty("password")); return ds; }
/* * Closes all active and idle connections in the pool */ public void forceCloseAll() { // 关闭pool里的所有连接,两个list中的连接都移除且关闭 synchronized (state) { expectedConnectionTypeCode = assembleConnectionTypeCode( dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword()); for (int i = state.activeConnections.size(); i > 0; i--) { // 遍历活动连接list try { PooledConnection conn = state.activeConnections.remove(i - 1); // 从活动连接list移出 conn.invalidate(); // PooledConnection的valid设为false Connection realConn = conn.getRealConnection(); // 获取真conn (java.sql.Connection) if (!realConn.getAutoCommit()) { // 不是自动提交的话 realConn.rollback(); // 回滚 } realConn.close(); } catch (Exception e) { // ignore } } for (int i = state.idleConnections.size(); i > 0; i--) { // 简历空闲连接list try { PooledConnection conn = state.idleConnections.remove(i - 1); conn.invalidate(); Connection realConn = conn.getRealConnection(); if (!realConn.getAutoCommit()) { realConn.rollback(); } realConn.close(); } catch (Exception e) { // ignore } } } if (log.isDebugEnabled()) { log.debug("PooledDataSource forcefully closed/removed all connections."); } }
/* * Closes all active and idle connections in the pool */ public void forceCloseAll() { synchronized (state) { expectedConnectionTypeCode = assembleConnectionTypeCode( dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword()); for (int i = state.activeConnections.size(); i > 0; i--) { try { PooledConnection conn = (PooledConnection) state.activeConnections.remove(i - 1); conn.invalidate(); Connection realConn = conn.getRealConnection(); if (!realConn.getAutoCommit()) { realConn.rollback(); } realConn.close(); } catch (Exception e) { // ignore } } for (int i = state.idleConnections.size(); i > 0; i--) { try { PooledConnection conn = (PooledConnection) state.idleConnections.remove(i - 1); conn.invalidate(); Connection realConn = conn.getRealConnection(); if (!realConn.getAutoCommit()) { realConn.rollback(); } realConn.close(); } catch (Exception e) { // ignore } } } if (log.isDebugEnabled()) { log.debug("PooledDataSource forcefully closed/removed all connections."); } }
public Properties getDriverProperties() { return dataSource.getDriverProperties(); }
public void setDefaultTransactionIsolationLevel(Integer defaultTransactionIsolationLevel) { dataSource.setDefaultTransactionIsolationLevel(defaultTransactionIsolationLevel); forceCloseAll(); }
public boolean isAutoCommit() { return dataSource.isAutoCommit(); }
public Integer getDefaultTransactionIsolationLevel() { return dataSource.getDefaultTransactionIsolationLevel(); }
public String getUsername() { return dataSource.getUsername(); }
public String getPassword() { return dataSource.getPassword(); }
private PooledConnection popConnection(String username, String password) throws SQLException { boolean countedWait = false; PooledConnection conn = null; long t = System.currentTimeMillis(); int localBadConnectionCount = 0; while (conn == null) { synchronized (state) { if (state.idleConnections.size() > 0) { // Pool has available connection conn = (PooledConnection) 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 = new PooledConnection(dataSource.getConnection(), this); @SuppressWarnings("unused") // used in logging, if enabled Connection realConn = conn.getRealConnection(); if (log.isDebugEnabled()) { log.debug("Created connection " + conn.getRealHashCode() + "."); } } else { // Cannot create new connection PooledConnection oldestActiveConnection = (PooledConnection) state.activeConnections.get(0); long longestCheckoutTime = oldestActiveConnection.getCheckoutTime(); if (longestCheckoutTime > poolMaximumCheckoutTime) { // Can claim overdue connection state.claimedOverdueConnectionCount++; state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime; state.accumulatedCheckoutTime += longestCheckoutTime; state.activeConnections.remove(oldestActiveConnection); if (!oldestActiveConnection.getRealConnection().getAutoCommit()) { oldestActiveConnection.getRealConnection().rollback(); } conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this); oldestActiveConnection.invalidate(); if (log.isDebugEnabled()) { log.debug("Claimed overdue connection " + conn.getRealHashCode() + "."); } } else { // Must wait try { if (!countedWait) { state.hadToWaitCount++; countedWait = true; } if (log.isDebugEnabled()) { log.debug( "Waiting as long as " + poolTimeToWait + " milliseconds for connection."); } long wt = System.currentTimeMillis(); state.wait(poolTimeToWait); state.accumulatedWaitTime += System.currentTimeMillis() - wt; } catch (InterruptedException e) { break; } } } } if (conn != null) { 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 + 3)) { if (log.isDebugEnabled()) { log.debug("PooledDataSource: Could not get a good connection to the database."); } throw new SQLException( "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."); } throw new SQLException( "PooledDataSource: Unknown severe error condition. The connection pool returned a null connection."); } return conn; }
public String getUrl() { return dataSource.getUrl(); }
private PooledConnection popConnection(String username, String password) throws SQLException { // 获取一个连接 boolean countedWait = false; PooledConnection conn = null; long t = System.currentTimeMillis(); int localBadConnectionCount = 0; while (conn == null) { synchronized (state) { if (!state.idleConnections.isEmpty()) { // pool里还有空闲连接 // Pool has available connection conn = state.idleConnections.remove(0); // 从空闲list移出一个conn,用做新连接 if (log.isDebugEnabled()) { log.debug("Checked out connection " + conn.getRealHashCode() + " from pool."); } } else { // pool里没有空闲连接了 // Pool does not have available connection if (state.activeConnections.size() < poolMaximumActiveConnections) { // 活动list没有满 // Can create new connection conn = new PooledConnection(dataSource.getConnection(), this); // 新建一个PooledConnection if (log.isDebugEnabled()) { log.debug("Created connection " + conn.getRealHashCode() + "."); } } else { // 活动list已经满了,无法创建新连接 // Cannot create new connection PooledConnection oldestActiveConnection = state.activeConnections.get(0); // 获取最早开始活动的连接 long longestCheckoutTime = oldestActiveConnection.getCheckoutTime(); // 获得最老的活动连接的checkout时间 if (longestCheckoutTime > poolMaximumCheckoutTime) { // 如果checkout时间大于最大值 // Can claim overdue connection state.claimedOverdueConnectionCount++; // 过期连接计数++ state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime; // 累加过期连接的checkout时间 state.accumulatedCheckoutTime += longestCheckoutTime; // 累加checkout时间 state.activeConnections.remove(oldestActiveConnection); // 从活动list移出最老的活动连接,留出空位来啦 if (!oldestActiveConnection.getRealConnection().getAutoCommit()) { oldestActiveConnection.getRealConnection().rollback(); // 回滚 } conn = new PooledConnection( oldestActiveConnection.getRealConnection(), this); // 新建连接,用最老连接的真连接 oldestActiveConnection.invalidate(); // 最老连接标记无效 if (log.isDebugEnabled()) { log.debug("Claimed overdue connection " + conn.getRealHashCode() + "."); } } else { // 如果checkout时间并没有超过最大值,必须等待 // Must wait try { if (!countedWait) { // countedWait原来是false state.hadToWaitCount++; // 必须等待的计数++ countedWait = true; // countedWait变为true } if (log.isDebugEnabled()) { log.debug( "Waiting as long as " + poolTimeToWait + " milliseconds for connection."); } long wt = System.currentTimeMillis(); state.wait( poolTimeToWait); // 等poolTimeToWait微秒,pushConnection移出一个连接时会notifyAll来唤醒wait的线程 state.accumulatedWaitTime += System.currentTimeMillis() - wt; } catch (InterruptedException e) { break; } } } } if (conn != null) { // conn非空,确实建出来了 if (conn.isValid()) { // conn有效 if (!conn.getRealConnection().getAutoCommit()) { conn.getRealConnection().rollback(); // 这里回滚是干啥? hama } conn.setConnectionTypeCode( assembleConnectionTypeCode(dataSource.getUrl(), username, password)); conn.setCheckoutTimestamp(System.currentTimeMillis()); conn.setLastUsedTimestamp(System.currentTimeMillis()); state.activeConnections.add(conn); // 加入活动list state.requestCount++; state.accumulatedRequestTime += System.currentTimeMillis() - t; } else { // conn无效 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 + 3)) { if (log.isDebugEnabled()) { log.debug("PooledDataSource: Could not get a good connection to the database."); } throw new SQLException( "PooledDataSource: Could not get a good connection to the database."); } } } } } // 到这里while结束 if (conn == null) { // 出现了奇葩的Unknown错吧 if (log.isDebugEnabled()) { log.debug( "PooledDataSource: Unknown severe error condition. The connection pool returned a null connection."); } throw new SQLException( "PooledDataSource: Unknown severe error condition. The connection pool returned a null connection."); } return conn; }
public Connection getConnection() throws SQLException { return popConnection(dataSource.getUsername(), dataSource.getPassword()).getProxyConnection(); }
public void setDefaultAutoCommit(boolean defaultAutoCommit) { dataSource.setAutoCommit(defaultAutoCommit); forceCloseAll(); }
public void setPassword(String password) { dataSource.setPassword(password); forceCloseAll(); }
public void setUsername(String username) { dataSource.setUsername(username); forceCloseAll(); }
public void setUrl(String url) { dataSource.setUrl(url); forceCloseAll(); }
public void setDriver(String driver) { dataSource.setDriver(driver); forceCloseAll(); }
public PooledDataSource(String driver, String url, String username, String password) { dataSource = new UnpooledDataSource(driver, url, username, password); expectedConnectionTypeCode = assembleConnectionTypeCode( dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword()); }
public void setDriverProperties(Properties driverProps) { dataSource.setDriverProperties(driverProps); forceCloseAll(); }
@Override public Connection getConnection() throws SQLException { // 获得连接,即popConnection(...).getProxyConnection()获得代理连接 return popConnection(dataSource.getUsername(), dataSource.getPassword()).getProxyConnection(); }
public String getDriver() { return dataSource.getDriver(); }