`

可供参考的【数据库连接池(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);
	}
}
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics