cs6320 – connection pooling

10
CS6320 – CS6320 – Connection Pooling Connection Pooling

Upload: brie

Post on 14-Jan-2016

68 views

Category:

Documents


0 download

DESCRIPTION

CS6320 – Connection Pooling. Connection pooling....the need. Creation of each connection – DriverManager.getConnection() – uses resources and takes time. Program may only execute for a small while. But, many clients may be making program requests. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: CS6320 – Connection Pooling

CS6320 – Connection CS6320 – Connection PoolingPooling

Page 2: CS6320 – Connection Pooling

Connection pooling....the needConnection pooling....the need

Creation of each connection – DriverManager.getConnection() Creation of each connection – DriverManager.getConnection() – – uses resources and takes time.uses resources and takes time.

Program may only execute for a small while.Program may only execute for a small while. But, many clients may be making program requests.But, many clients may be making program requests. It would be better, if the programs could re-use connections It would be better, if the programs could re-use connections

from a pool (array) of database connections.from a pool (array) of database connections. A separate process may manage the connections and open A separate process may manage the connections and open

new ones, if the existing ones are not enough.new ones, if the existing ones are not enough.

Page 3: CS6320 – Connection Pooling

Services of a connection poolServices of a connection pool

When connection pool manager is started, it When connection pool manager is started, it starts up a (configurable) number of database starts up a (configurable) number of database connections.connections.

The programs can request connections and The programs can request connections and release them, when they are not needed.release them, when they are not needed.

If all connections are in use, then e.g. the If all connections are in use, then e.g. the following possibilities exist:following possibilities exist:

- Wait for a free connection.- Wait for a free connection.- Fail as there were no free connections. - Fail as there were no free connections. - Create a new connection.- Create a new connection.

Page 4: CS6320 – Connection Pooling

Connection pool implementationConnection pool implementation

JDBC 2.0 includes a connection pool, but there JDBC 2.0 includes a connection pool, but there are also other implementations.are also other implementations.

A typical implementation has a class, whose A typical implementation has a class, whose services are available using static methods.services are available using static methods.

This way, the manager can be found using This way, the manager can be found using method Class.forName() method Class.forName() • This gives access to connections.This gives access to connections.

Page 5: CS6320 – Connection Pooling

Sample Code from “Core Servlets” by Hall et. al.Sample Code from “Core Servlets” by Hall et. al.public class ConnectionPool implements Runnable {public class ConnectionPool implements Runnable { private String driver, url, username, password;private String driver, url, username, password; private int maxConnections;private int maxConnections; private boolean waitIfBusy;private boolean waitIfBusy; private Vector availableConnections, busyConnections;private Vector availableConnections, busyConnections; private boolean connectionPending = false;private boolean connectionPending = false;

public ConnectionPool(String driver, String url,public ConnectionPool(String driver, String url, String username, String password, int initialConnections,String username, String password, int initialConnections,

int maxConnections,int maxConnections, boolean waitIfBusy)boolean waitIfBusy) throws SQLException {throws SQLException { this.driver = driver;this.driver = driver; this.url = url;this.url = url; this.username = username;this.username = username; this.password = password;this.password = password; this.maxConnections = maxConnections;this.maxConnections = maxConnections; this.waitIfBusy = waitIfBusy;this.waitIfBusy = waitIfBusy; if (initialConnections > maxConnections) {if (initialConnections > maxConnections) { initialConnections = maxConnections;initialConnections = maxConnections; }} availableConnections = new Vector(initialConnections);availableConnections = new Vector(initialConnections); busyConnections = new Vector();busyConnections = new Vector(); for(int i=0; i<initialConnections; i++) {for(int i=0; i<initialConnections; i++) { availableConnections.addElement(makeNewConnection());availableConnections.addElement(makeNewConnection()); }} }}

Page 6: CS6320 – Connection Pooling

public synchronized Connection getConnection()public synchronized Connection getConnection() throws SQLException {throws SQLException { if (!availableConnections.isEmpty()) {if (!availableConnections.isEmpty()) { Connection existingConnection =Connection existingConnection = (Connection)availableConnections.lastElement();(Connection)availableConnections.lastElement(); int lastIndex = availableConnections.size() - 1;int lastIndex = availableConnections.size() - 1; availableConnections.removeElementAt(lastIndex);availableConnections.removeElementAt(lastIndex); // If connection on available list is closed (e.g.,// If connection on available list is closed (e.g., // it timed out), then remove it from available list// it timed out), then remove it from available list // and repeat the process of obtaining a connection.// and repeat the process of obtaining a connection. // Also wake up threads that were waiting for a// Also wake up threads that were waiting for a // connection because maxConnection limit was reached.// connection because maxConnection limit was reached. if (existingConnection.isClosed()) {if (existingConnection.isClosed()) { notifyAll(); // Freed up a spot for anybody waitingnotifyAll(); // Freed up a spot for anybody waiting return(getConnection());return(getConnection()); } else {} else { busyConnections.addElement(existingConnection);busyConnections.addElement(existingConnection); return(existingConnection);return(existingConnection); }}

Page 7: CS6320 – Connection Pooling

} else {} else { // Three possible cases:// Three possible cases: // 1) You haven't reached maxConnections limit. So// 1) You haven't reached maxConnections limit. So // establish one in the background if there isn't// establish one in the background if there isn't // already one pending, then wait for// already one pending, then wait for // the next available connection (whether or not// the next available connection (whether or not // it was the newly established one).// it was the newly established one). // 2) You reached maxConnections limit and waitIfBusy// 2) You reached maxConnections limit and waitIfBusy // flag is false. Throw SQLException in such a case.// flag is false. Throw SQLException in such a case. // 3) You reached maxConnections limit and waitIfBusy// 3) You reached maxConnections limit and waitIfBusy // flag is true. Then do the same thing as in second// flag is true. Then do the same thing as in second // part of step 1: wait for next available connection.// part of step 1: wait for next available connection. if ((totalConnections() < maxConnections) &&if ((totalConnections() < maxConnections) && !connectionPending) {!connectionPending) { makeBackgroundConnection();makeBackgroundConnection(); } else if (!waitIfBusy) {} else if (!waitIfBusy) { throw new SQLException("Connection limit reached");throw new SQLException("Connection limit reached"); }} // Wait for either a new connection to be established// Wait for either a new connection to be established // (if you called makeBackgroundConnection) or for// (if you called makeBackgroundConnection) or for // an existing connection to be freed up.// an existing connection to be freed up. try {try { wait();wait(); } catch(InterruptedException ie) {}} catch(InterruptedException ie) {} // Someone freed up a connection, so try again.// Someone freed up a connection, so try again. return(getConnection());return(getConnection()); }} }}

Page 8: CS6320 – Connection Pooling

// You can't just make a new connection in the foreground// You can't just make a new connection in the foreground // when none are available, since this can take several// when none are available, since this can take several // seconds with a slow network connection. Instead,// seconds with a slow network connection. Instead, // start a thread that establishes a new connection,// start a thread that establishes a new connection, // then wait. You get woken up either when the new connection// then wait. You get woken up either when the new connection // is established or if someone finishes with an existing// is established or if someone finishes with an existing // connection.// connection.

private void makeBackgroundConnection() {private void makeBackgroundConnection() { connectionPending = true;connectionPending = true; try {try { Thread connectThread = new Thread(this);Thread connectThread = new Thread(this); connectThread.start();connectThread.start(); } catch(OutOfMemoryError oome) {} catch(OutOfMemoryError oome) { // Give up on new connection// Give up on new connection }} }}

public void run() {public void run() { try {try { Connection connection = makeNewConnection();Connection connection = makeNewConnection(); synchronized(this) {synchronized(this) { availableConnections.addElement(connection);availableConnections.addElement(connection); connectionPending = false;connectionPending = false; notifyAll();notifyAll(); }} } catch(Exception e) { // SQLException or OutOfMemory} catch(Exception e) { // SQLException or OutOfMemory // Give up on new connection and wait for existing one// Give up on new connection and wait for existing one // to free up.// to free up. }} }}

Page 9: CS6320 – Connection Pooling

// This explicitly makes a new connection. Called in// This explicitly makes a new connection. Called in // the foreground when initializing the ConnectionPool,// the foreground when initializing the ConnectionPool, // and called in the background when running.// and called in the background when running. private Connection makeNewConnection()private Connection makeNewConnection() throws SQLException {throws SQLException { try {try { // Load database driver if not already loaded// Load database driver if not already loaded Class.forName(driver);Class.forName(driver); // Establish network connection to database// Establish network connection to database Connection connection =Connection connection = DriverManager.getConnection(url, username, password);DriverManager.getConnection(url, username, password); return(connection);return(connection); } catch(ClassNotFoundException cnfe) {} catch(ClassNotFoundException cnfe) { // Simplify try/catch blocks of people using this by// Simplify try/catch blocks of people using this by // throwing only one exception type.// throwing only one exception type. throw new SQLException("Can't find class for driver: " +throw new SQLException("Can't find class for driver: " + driver);driver); }} }}

public synchronized void free(Connection connection) {public synchronized void free(Connection connection) { busyConnections.removeElement(connection);busyConnections.removeElement(connection); availableConnections.addElement(connection);availableConnections.addElement(connection); // Wake up threads that are waiting for a connection// Wake up threads that are waiting for a connection notifyAll(); notifyAll(); }} public synchronized int totalConnections() {public synchronized int totalConnections() { return(availableConnections.size() +return(availableConnections.size() + busyConnections.size());busyConnections.size()); }}

Page 10: CS6320 – Connection Pooling

/** Close all the connections. Use with caution:/** Close all the connections. Use with caution: * be sure no connections are in use before* be sure no connections are in use before * calling. Note that you are not <I>required</I> to* calling. Note that you are not <I>required</I> to * call this when done with a ConnectionPool, since* call this when done with a ConnectionPool, since * connections are guaranteed to be closed when* connections are guaranteed to be closed when * garbage collected. But this method gives more control* garbage collected. But this method gives more control * regarding when the connections are closed.* regarding when the connections are closed. */*/public synchronized void closeAllConnections() {public synchronized void closeAllConnections() { closeConnections(availableConnections);closeConnections(availableConnections); availableConnections = new Vector();availableConnections = new Vector(); closeConnections(busyConnections);closeConnections(busyConnections); busyConnections = new Vector();busyConnections = new Vector(); }} private void closeConnections(Vector connections) {private void closeConnections(Vector connections) { try {try { for(int i=0; i<connections.size(); i++) {for(int i=0; i<connections.size(); i++) { Connection connection =Connection connection = (Connection)connections.elementAt(i);(Connection)connections.elementAt(i); if (!connection.isClosed()) {if (!connection.isClosed()) { connection.close();connection.close(); }} }} } catch(SQLException sqle) {} catch(SQLException sqle) { // Ignore errors; garbage collect anyhow// Ignore errors; garbage collect anyhow }} }} public synchronized String toString() {public synchronized String toString() { String info =String info = "ConnectionPool(" + url + "," + username + ")" +"ConnectionPool(" + url + "," + username + ")" + ", available=" + availableConnections.size() +", available=" + availableConnections.size() + ", busy=" + busyConnections.size() +", busy=" + busyConnections.size() + ", max=" + maxConnections;", max=" + maxConnections; return(info);return(info); }}}}