可供参考的【数据库连接池(DBCP)】二
可供参考的【数据库连接池(DBCP)】2
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; import java.util.Vector; public class PersonDefine_ConnectionPool implements Runnable { public String ProductionDB = "axdb_tmp";//給的默認值 private String database_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";//給的默認值 // private String // dakabase_url="jdbc:sybase:Tds:IP:port/dakabase_test?useUnicode=true&characterEncoding=UTF-8"; private String database_url = "jdbc:sqlserver://localhost:1433;DatabaseName=mgr_live"; //給的默認值 private String username = "sa"; private String password = "12345678"; private int maxConnections = 50; private boolean waitIfBusy = true; private Vector availableConnections, busyConnections; private boolean connectionPending = false; public PersonDefine_ConnectionPool(Properties props) throws SQLException { System.out.println("jdbc:PersonDefine_ConnectionPool..."); int initialConnections = 0; this.ProductionDB = props.getProperty("ELITEDATA.ProductionDB"); this.database_driver = props.getProperty("ELITEDATA.database_driver").trim(); this.database_url = props.getProperty("ELITEDATA.database_url"); this.username=props.getProperty("ELITEDATA.database_username"); this.password=props.getProperty("ELITEDATA.database_password"); this.maxConnections = maxConnections; this.waitIfBusy = waitIfBusy; if (initialConnections > maxConnections) { initialConnections = maxConnections; } availableConnections = new Vector(initialConnections); busyConnections = new Vector(); for (int i = 0; i < initialConnections; i++) { availableConnections.addElement(makeNewConnection()); } } public synchronized Connection getConnection() throws SQLException { System.out.println("jdbc:Get PersonDefine_ConnectionPool..."); if (!availableConnections.isEmpty()) { Connection existingConnection = (Connection) availableConnections.lastElement(); int lastIndex = availableConnections.size() - 1; availableConnections.removeElementAt(lastIndex); // If connection on available list is closed (e.g., // it timed out), then remove it from available list // and repeat the process of obtaining a connection. // Also wake up threads that were waiting for a // connection because maxConnection limit was reached. if (existingConnection.isClosed()) { notifyAll(); // Freed up a spot for anybody waiting return (getConnection()); } else { busyConnections.addElement(existingConnection); return (existingConnection); } } else { // Three possible cases: // 1) You haven't reached maxConnections limit. So // establish one in the background if there isn't // already one pending, then wait for // the next available connection (whether or not // it was the newly established one). // 2) You reached maxConnections limit and waitIfBusy // flag is false. Throw SQLException in such a case. // 3) You reached maxConnections limit and waitIfBusy // flag is true. Then do the same thing as in second // part of step 1: wait for next available connection. if ((totalConnections() < maxConnections) && !connectionPending) { makeBackgroundConnection(); } else if (!waitIfBusy) { throw new SQLException("PersonDefine_ConnectionPool limit reached"); } // Wait for either a new connection to be established // (if you called makeBackgroundConnection) or for // an existing connection to be freed up. try { wait(); } catch (InterruptedException ie) { } // Someone freed up a connection, so try again. return (getConnection()); } } // You can't just make a new connection in the foreground // when none are available, since this can take several // seconds with a slow network connection. Instead, // start a thread that establishes a new connection, // then wait. You get woken up either when the new connection // is established or if someone finishes with an existing // connection. private void makeBackgroundConnection() { connectionPending = true; System.out.println("jdbc:Make Background PersonDefine_ConnectionPool..."); try { Thread connectThread = new Thread(this); connectThread.start(); } catch (OutOfMemoryError oome) { System.out.println("jdbc:PersonDefine_ConnectionPool out of Memory..." + oome); } } public void run() { try { System.out.println("jdbc:run PersonDefine_ConnectionPool..."); Connection connection = makeNewConnection(); synchronized (this) { availableConnections.addElement(connection); connectionPending = false; notifyAll(); } } catch (Exception e) { // SQLException or OutOfMemory System.out.println("jdbc:PersonDefine_ConnectionPool out of Memory..."); } } // This explicitly makes a new connection. Called in // the foreground when initializing the ConnectionPool, // and called in the background when running. private Connection makeNewConnection() throws SQLException { try { System.out.println("jdbc:make new PersonDefine_ConnectionPool..."); // Load database dakabase_driver if not already loaded Class.forName(database_driver); // Establish network connection to database Connection connection = DriverManager.getConnection(database_url, username, password); return (connection); } catch (ClassNotFoundException cnfe) { // Simplify try/catch blocks of people using this by // throwing only one exception type. System.out.println("jdbc:PersonDefine_ConnectionPool Can't find class for database_driver:"); throw new SQLException("Can't find class for PersonDefine_ConnectionPool: " + database_driver); } } public synchronized void free(Connection connection) { System.out.println("jdbc:free PersonDefine_ConnectionPool..."); busyConnections.removeElement(connection); availableConnections.addElement(connection); // Wake up threads that are waiting for a connection notifyAll(); } public synchronized int totalConnections() { return (availableConnections.size() + busyConnections.size()); } /** * Close all the connections. Use with caution: be sure no connections are * in use before calling. Note that you are not <I>required</I> to call * this when done with a ConnectionPool, since connections are guaranteed to * be closed when garbage collected. But this method gives more control * regarding when the connections are closed. */ public synchronized void closeAllConnections() { System.out.println("jdbc:close all PersonDefine_ConnectionPool..."); closeConnections(availableConnections); availableConnections = new Vector(); closeConnections(busyConnections); busyConnections = new Vector(); } private void closeConnections(Vector connections) { try { System.out.println("jdbc:close PersonDefine_ConnectionPool..."); for (int i = 0; i < connections.size(); i++) { Connection connection = (Connection) connections.elementAt(i); if (!connection.isClosed()) { connection.close(); } } } catch (SQLException sqle) { System.out.println("jdbc: PersonDefine_ConnectionPool..." + sqle); } } public synchronized String toString() { String info = "ConnectionPool(PersonDefine_ConnectionPool)(" + database_url + "," + username + ")" + ", available=" + availableConnections.size() + ", busy=" + busyConnections.size() + ", max=" + maxConnections; return (info); } }