📄 connectionpool.java
字号:
* @return An existing or new database connection. * @throws Exception if the pool is empty */ private PooledConnection popConnection() throws Exception { while (!pool.empty()) { PooledConnection con = (PooledConnection) pool.pop(); // It's really not safe to assume this connection is // valid even though it's checked before being pooled. if (isValid(con)) { return con; } else { // Close invalid connection. con.close(); totalConnections--; // If the pool is now empty, create a new connection. We're // guaranteed not to exceed the connection limit since we // just killed off one or more invalid connections, and no // one else can be accessing this cache right now. if (pool.empty()) { return getNewConnection(); } } } // The connection pool was empty to start with--don't call this // routine if there's no connection to pop! // TODO: Propose general Turbine assertion failure exception? -PGO throw new Exception("Assertion failure: Attempted to pop " + "connection from empty pool!"); } /** * Helper method which determines whether a connection has expired. * * @param pc The connection to test. * @return True if the connection is expired, false otherwise. */ private boolean isExpired(PooledConnection pc) { // Test the age of the connection (defined as current time // minus connection birthday) against the connection pool // expiration time. long birth = ((Long) timeStamps.get(pc)).longValue(); long age = System.currentTimeMillis() - birth; boolean dead = (expiryTime > 0) ? age > expiryTime : age > DEFAULT_EXPIRY_TIME; return dead; // He is dead, Jim. } /** * Determines if a connection is still valid. * * @param connection The connection to test. * @return True if the connection is valid, false otherwise. */ private boolean isValid(PooledConnection connection) { // all this code is commented out because // connection.getConnection() is called when the connection // is returned to the pool and it will open a new logical Connection // which does not get closed, then when it is called again // when a connection is requested it likely fails because a // new Connection has been requested and the old one is still // open. need to either do it right or skip it. null check // was not working either. //try //{ // This will throw an exception if: // The connection is null // The connection is closed // Therefore, it would be false. //connection.getConnection(); // Check for expiration return !isExpired(connection); /* } catch (SQLException e) { return false; } */ } /** * Close any open connections when this object is garbage collected. * * @exception Throwable Anything might happen... */ protected void finalize() throws Throwable { shutdown(); } /** * Close all connections to the database, */ void shutdown() { if (pool != null) { while (!pool.isEmpty()) { try { ((PooledConnection) pool.pop()).close(); } catch (SQLException ignore) { } finally { totalConnections--; } } } monitor.shutdown(); } /** * Returns the Total connections in the pool * * @return total connections in the pool */ int getTotalCount() { return totalConnections; } /** * Returns the available connections in the pool * * @return number of available connections in the pool */ int getNbrAvailable() { return pool.size(); } /** * Returns the checked out connections in the pool * * @return number of checked out connections in the pool */ int getNbrCheckedOut() { return (totalConnections - pool.size()); } /** * Decreases the count of connections in the pool * and also calls <code>notify()</code>. */ void decrementConnections() { totalConnections--; notify(); } /** * Get the name of the pool * * @return the name of the pool */ String getPoolName() { return toString(); } // *********************************************************************** // java.sql.ConnectionEventListener implementation // *********************************************************************** /** * This will be called if the Connection returned by the getConnection * method came from a PooledConnection, and the user calls the close() * method of this connection object. What we need to do here is to * release this PooledConnection from our pool... * * @param event the connection event */ public void connectionClosed(ConnectionEvent event) { releaseConnection((PooledConnection) event.getSource()); } /** * If a fatal error occurs, close the underlying physical connection so as * not to be returned in the future * * @param event the connection event */ public void connectionErrorOccurred(ConnectionEvent event) { try { System.err.println("CLOSING DOWN CONNECTION DUE TO INTERNAL ERROR"); //remove this from the listener list because we are no more //interested in errors since we are about to close this connection ((PooledConnection) event.getSource()) .removeConnectionEventListener(this); } catch (Exception ignore) { //just ignore } try { closePooledConnection((PooledConnection) event.getSource()); } catch (Exception ignore) { //just ignore } } /** * This method returns a connection to the pool, and <b>must</b> * be called by the requestor when finished with the connection. * * @param pcon The database connection to release. */ private synchronized void releaseConnection(PooledConnection pcon) { if (isValid(pcon)) { pool.push(pcon); notify(); } else { closePooledConnection(pcon); } } /** * * @param pcon The database connection to close. */ private void closePooledConnection(PooledConnection pcon) { try { pcon.close(); timeStamps.remove(pcon); } catch (Exception e) { log.error("Error occurred trying to close a PooledConnection.", e); } finally { decrementConnections(); } } /////////////////////////////////////////////////////////////////////////// /** * This inner class monitors the <code>PoolBrokerService</code>. * * This class is capable of logging the number of connections available in * the pool periodically. This can prove useful if you application * frozes after certain amount of time/requests and you suspect * that you have connection leakage problem. * * Set the <code>logInterval</code> property of your pool definition * to the number of seconds you want to elapse between loging the number of * connections. */ protected class Monitor extends Thread { /** true if the monot is running */ private boolean isRun = true; /** * run method for the monitor thread */ public void run() { StringBuffer buf = new StringBuffer(); while (logInterval > 0 && isRun) { buf.setLength(0); buf.append(getPoolName()); buf.append(" avail: ").append(getNbrAvailable()); buf.append(" in use: ").append(getNbrCheckedOut()); buf.append(" total: ").append(getTotalCount()); log.info(buf.toString()); // Wait for a bit. try { Thread.sleep(logInterval); } catch (InterruptedException ignored) { } } } /** * Shut down the monitor */ public void shutdown() { isRun = false; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -