/** Pings live connections. */ public synchronized void doPing() throws SQLException { SQLException se = null; boolean foundHost = false; int pingTimeout = this.currentConnection.getLoadBalancePingTimeout(); for (Iterator<String> i = this.hostList.iterator(); i.hasNext(); ) { String host = i.next(); ConnectionImpl conn = this.liveConnections.get(host); if (conn == null) { continue; } try { if (pingTimeout == 0) { conn.ping(); } else { conn.pingInternal(true, pingTimeout); } foundHost = true; } catch (SQLException e) { this.activePhysicalConnections--; // give up if it is the current connection, otherwise NPE faking resultset later. if (host.equals(this.connectionsToHostsMap.get(this.currentConnection))) { // clean up underlying connections, since connection pool won't do it closeAllConnections(); this.isClosed = true; this.closedReason = "Connection closed because ping of current connection failed."; throw e; } // if the Exception is caused by ping connection lifetime checks, don't add to blacklist if (e.getMessage().equals(Messages.getString("Connection.exceededConnectionLifetime"))) { // only set the return Exception if it's null if (se == null) { se = e; } } else { // overwrite the return Exception no matter what se = e; if (isGlobalBlacklistEnabled()) { addToGlobalBlacklist(host); } } // take the connection out of the liveConnections Map this.liveConnections.remove(this.connectionsToHostsMap.get(conn)); } } // if there were no successful pings if (!foundHost) { closeAllConnections(); this.isClosed = true; this.closedReason = "Connection closed due to inability to ping any active connections."; // throw the stored Exception, if exists if (se != null) { throw se; } // or create a new SQLException and throw it, must be no liveConnections ((ConnectionImpl) this.currentConnection).throwConnectionClosedException(); } }
/** * Picks the "best" connection to use for the next transaction based on the BalanceStrategy in * use. * * @throws SQLException */ @Override synchronized void pickNewConnection() throws SQLException { if (this.isClosed && this.closedExplicitly) { return; } if (this.currentConnection == null) { // startup this.currentConnection = this.balancer.pickConnection( this, Collections.unmodifiableList(this.hostList), Collections.unmodifiableMap(this.liveConnections), this.responseTimes.clone(), this.retriesAllDown); return; } if (this.currentConnection.isClosed()) { invalidateCurrentConnection(); } int pingTimeout = this.currentConnection.getLoadBalancePingTimeout(); boolean pingBeforeReturn = this.currentConnection.getLoadBalanceValidateConnectionOnSwapServer(); for (int hostsTried = 0, hostsToTry = this.hostList.size(); hostsTried < hostsToTry; hostsTried++) { ConnectionImpl newConn = null; try { newConn = this.balancer.pickConnection( this, Collections.unmodifiableList(this.hostList), Collections.unmodifiableMap(this.liveConnections), this.responseTimes.clone(), this.retriesAllDown); if (this.currentConnection != null) { if (pingBeforeReturn) { if (pingTimeout == 0) { newConn.ping(); } else { newConn.pingInternal(true, pingTimeout); } } syncSessionState(this.currentConnection, newConn); } this.currentConnection = newConn; return; } catch (SQLException e) { if (shouldExceptionTriggerConnectionSwitch(e) && newConn != null) { // connection error, close up shop on current connection invalidateConnection(newConn); } } } // no hosts available to swap connection to, close up. this.isClosed = true; this.closedReason = "Connection closed after inability to pick valid new connection during load-balance."; }