📄 connectionpool.java
字号:
package org.ehotsoft.yekki.sql.pool;import java.sql.*;import java.util.*;import java.io.InputStream;import java.math.BigDecimal;import java.sql.Date;public class ConnectionPool { Vector connVector, closeVector; String url; private Queue waitingThreads; private String username, password, alias; private int maxConn, timeoutSeconds, checkoutSeconds, numCheckoutTimeout; private int numRequests, numWaits, maxCheckout; private boolean cacheStatements; int numConnectionFaults = 0; private boolean trace; private int prefetchSize = -1; public ConnectionPool( String alias, String url, String username, String password, int maxConn, int timeoutSeconds, int checkoutSeconds ) { this( alias, url, username, password, maxConn, timeoutSeconds, checkoutSeconds, 0 ); } public ConnectionPool( String alias, String url, String username, String password, int maxConn, int timeoutSeconds, int checkoutSeconds, int maxCheckout ) { this.timeoutSeconds = timeoutSeconds; this.checkoutSeconds = checkoutSeconds; this.alias = alias; this.url = url; this.username = username; this.password = password; this.maxConn = maxConn; this.maxCheckout = maxCheckout; this.numRequests = 0; this.numWaits = 0; this.numCheckoutTimeout = 0; connVector = new Vector( maxConn ); closeVector = new Vector( maxConn ); waitingThreads = new Queue(); trace = false; cacheStatements = true; } public void setCacheStatements( boolean cacheStatements ) { this.cacheStatements = cacheStatements; } public boolean getCacheStatements() { return cacheStatements; } public void setTracing( boolean on ) { trace = on; } public String getAlias() { return alias; } public int getNumRequests() { return numRequests; } public int getNumWaits() { return numWaits; } public int getNumCheckoutTimeouts() { return numCheckoutTimeout; } public int getMaxConn() { return maxConn; } public int size() { return connVector.size(); } public synchronized void reapIdleConnections() { synchronized( this ) { if ( trace ) { System.err.println("ConnectionPool: " + alias + " reapIdleConnections() starting, size="+ size() ); } long now = System.currentTimeMillis(); long idleTimeout = now - ( timeoutSeconds * 1000 ); long checkoutTimeout = now - ( checkoutSeconds * 1000 ); for( int i = 0; i < connVector.size(); ) { PooledConnection conn = ( PooledConnection )connVector.elementAt(i); if ( conn.isLocked() && ( conn.getLastAccess() < checkoutTimeout ) ) { numCheckoutTimeout++; System.err.println( "ConnectionPool: Warning: found timed-out connection\n" + conn.dumpInfo() ); removeConnection(conn); notifyAll(); } else if ( conn.getLastAccess() < idleTimeout && conn.getLock() ) { removeConnection(conn); conn.releaseLock(); notifyAll(); } else { i++; } } } closeConnections(); if ( trace ) { System.err.println("ConnectionPool: " + alias + " reapIdleConnections() finished" ); } }// FIXME: what do we do when a connection is in progress. Maybe we// pass a boolean to this method that tells us whether to shutdown// immediately, or to close connections as they are returned..// for now we'll just close 'em public synchronized void removeAllConnections() { if( trace ) { System.err.println("ConnectionPool: " + alias + " removeAllConnections() called" ); } while( !connVector.isEmpty() ) { PooledConnection conn = ( PooledConnection )connVector.firstElement(); removeConnection( conn ); } } private synchronized void removeConnection( PooledConnection conn, boolean closeConn ) { connVector.removeElement( conn ); if ( closeConn ) { closeConnection( conn ); } else { closeVector.addElement( conn ); } } private synchronized void removeConnection( PooledConnection conn ) { removeConnection( conn, false ); } public synchronized Connection getConnection() throws SQLException { if ( trace ) { System.err.println( "ConnectionPool: " + alias + " getConnection() called" ); } numRequests++; while ( true ) { PooledConnection p; for ( int i = 0; i < connVector.size(); i++ ) { p = ( PooledConnection )connVector.elementAt( i ); if ( p.getLock() ) return releaseConnection( p ); } if ( trace ) { System.err.println("ConnectionPool: " + alias + " all connections locked. calling" + " createConnection()" ); } if ( connVector.size() < maxConn ) { if (trace) { System.err.println("ConnectionPool: " + alias + " opening new connection to database size="+size()); } Connection conn = createDriverConnection(); if ( trace ) { System.err.println("ConnectionPool: " + alias + " finished opening new connection"); } if (prefetchSize != -1) { if (conn instanceof oracle.jdbc.driver.OracleConnection) { ( ( oracle.jdbc.driver.OracleConnection )conn ).setDefaultRowPrefetch( prefetchSize ); } } p = new PooledConnection( conn, this ); p.getLock(); connVector.addElement( p ); return releaseConnection( p ); } try { if(trace) { System.err.println( "ConnectionPool: " + alias + " pool is full. calling wait()" ); } numWaits++; wait(); } catch (InterruptedException e) { } if( trace ) { System.err.println( "ConnectionPool: " + alias + " awoken from wait(). trying to grab" + " an available connection" ); } } } private void closeConnections() { Vector closeTmp = ( Vector )closeVector.clone(); for ( int i = 0; i < closeTmp.size(); i++ ) { PooledConnection conn = ( PooledConnection )closeTmp.elementAt( i ); closeConnection( conn ); } } private void closeConnection( PooledConnection conn ) { try { closeVector.removeElement(conn); JavaAlarm alarm = new JavaAlarm( conn, 10000 ); } catch(TimeoutException e) { if(trace) e.printStackTrace(); System.err.println( "ConnectionPool: " + e ); } } private synchronized Connection releaseConnection( PooledConnection connection ) { if ( trace ) { try { throw new RuntimeException(); } catch ( RuntimeException e ) { connection.setTraceException( e ); } } return connection; } Connection createDriverConnection() throws SQLException { return DriverManager.getConnection( url, username, password ); } public synchronized void returnConnection( PooledConnection conn ) { if ( maxCheckout > 0 && conn.getCheckoutCount() >= maxCheckout ) { if ( trace ) { System.err.println("ConnectionPool: " + alias + " connection checked out max # of times." + " closing it." ); } removeConnection( conn ); } if ( trace ) { System.err.println( "ConnectionPool: " + alias + " releasing lock and calling notifyAll()" ); } conn.releaseLock(); notifyAll(); } public String dumpInfo() { String LS = System.getProperty( "line.separator" ); StringBuffer report = new StringBuffer(); report.append( "Pool: " ) .append( this.toString() ) .append( LS ) .append( "\tAlias: " ) .append( this.getAlias() ) .append( LS ) .append( "\tMax connections: " ) .append( this.getMaxConn() ) .append( LS ) .append( "\tURL: " ) .append( this.url ) .append( LS ) .append( "\tCheckouts: " ) .append( this.getNumRequests() ) .append( LS ) .append( "\tThread waits: " ) .append( this.getNumWaits() ) .append( LS ) .append( "\tConnections found closed: " ) .append( numConnectionFaults ) .append( LS ) .append( "\tConnections reaped by timeout: " ) .append( this.getNumCheckoutTimeouts() ) .append( LS ) .append( "\tConnections currently in pool: " ) .append( this.size() ) .append( LS ); Vector connectionVector = this.connVector; PooledConnection pc; for ( int i = 0 ; i < connectionVector.size(); i++ ) { pc = ( PooledConnection )connectionVector.elementAt(i); if ( pc != null ) { report.append( pc.dumpInfo() ); } } return report.toString(); } public void setPrefetchSize( int newPrefetchSize ) { prefetchSize = newPrefetchSize; } public int getPrefetchSize() { return prefetchSize; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -