Java Technology Home Page
A-Z Index

Java Developer Connection(SM)
Online Training

Downloads, APIs, Documentation
Java Developer Connection
Tutorials, Tech Articles, Training
Online Support
Community Discussion
News & Events from Everywhere
Products from Everywhere
How Java Technology is Used Worldwide
 
Training Index

Writing Advanced Applications
Chapter 8 Continued: Connection Pooling

[<<BACK] [CONTENTS] [NEXT>>]

If you have used a SQL or other similar tool to connect to a database and act on the data, you probably know that getting the connection and logging in is the part that takes the most time. An application can easily spend several seconds every time it needs to establish a connection.

In releases prior to JDBCTM 2.0 every database session requires a new connection and login even if the previous connection and login used the same table and user account. If you are using a JDBC release prior to 2.0 and want to improve performance, you can cache JDBC connections instead.

Cached connections are kept in a runtime object pool and can be used and reused as needed by the application. One way to implement the object pool is to make a simple hashtable of connection objects. However, a more flexible way to do it is to write a wrapper JDBC Driver that is an intermediary between the client application and database.

The wrapper approach works particularly well in an Enterprise Bean that uses Bean-managed persistence for two reasons: 1) Only one Driver class is loaded per Bean, and 2) specific connection details are handled outside the Bean.

This section explains how to write a wrapper JDBC Driver class.


Wrapper Classes

The wrapper JDBC Driver created for this examples consists of the following three classes:
  • JDCConnectionDriver
  • JDCConnectionPool
  • JDCConnection

Connection Driver

The JDCConnectionDriver.java class implements the java.sql.Driver interface, which provides methods to load drivers and create new database connections.

A JDCConnectionManager object is created by the application seeking a database connection. The application provides the database Uniform Resource Locator (URL) for the database, login user ID, and login password.

The JDCConnectionManager constructor does the following:

  • Registers the JDCConnectionManager object with the DriverManager.

  • Loads the Driver class passed to the constructor by the calling program.

  • Initializes a JDCConnectionPool object for the connections with the database URL, login user ID, and login password passed to the constructor by the calling program.
public JDCConnectionDriver(String driver, 
                String url, 
                String user, 
                String password) 
        throws  ClassNotFoundException,
                InstantiationException, 
                IllegalAccessException, 
                SQLException {

  DriverManager.registerDriver(this);
  Class.forName(driver).newInstance();
  pool = new JDCConnectionPool(url, user, password);
}
When the calling program needs a database connection, it calls the JDCConnectionDriver.connect method, which in turn, calls the JDCConnectionPool.getConnection method.

Connection Pool

The JDCConnectionPool.java class makes connections available to calling program in its getConnection method. This method searches for an available connection in the connection pool. If no connection is available from the pool, a new connection is created. If a connection is available from the pool, the getConnection method leases the connection and returns it to the calling program.
public synchronized Connection getConnection() 
	throws SQLException {

  JDCConnection c;
  for(int i = 0; i < connections.size(); i++) {
     c = (JDCConnection)connections.elementAt(i);
     if (c.lease()) {
        return c;
     }
  }

  Connection conn = DriverManager.getConnection(
			url, user, password);
  c = new JDCConnection(conn, this);
  c.lease();
  connections.addElement(c);
  return c;
}
The JDCConnection.java class represents a JDBC connection in the connection pool, and is essentially a wrapper around a real JDBC connection. The JDCConnection object maintains a state flag to indicate if the connection is in use and the time the connection was taken from the pool. This time is used by the ConnectionReaper.java class to identify hanging connections.

Deadlocks and Hangs

While many client and server databases have graceful ways to handle deadlocks and hangs so you do not have to write code to handle these situations, many of the newer, lightweight distributed databases are not so well equipped. The connection pool class provides a dead connection reaper to handle such situations.

The ConnectionReaper class decides a connection is dead if the following conditions are met.

  • The connection is flagged as being in use.
  • The connection is older than a preset connection time out.
  • The connection fails a validation check.
The validation check runs a simple SQL query over the connection to see if it throws an exception. In this example, the validation method requests the high-level description of the database tables. If a connection fails the validation test, it is closed, a new connection is initiated to the database, and added to the connection pool.
public boolean validate() {
  try {
     conn.getMetaData();
  }catch (Exception e) {
     return false;
  }
  return true;
}

Closing Connections

The connection is returned to the connection pool when the calling program calls the JDCConnection.close method in its finally clause.
public void close() throws SQLException {
  pool.returnConnection(this);
}

Example Application

You use a connection pool in an application in a similar way to how you would use any other JDBC driver. Here is the code for a Bean-managed RegistrationBean. This RegistrationBean is adapted from the auction house Enterprise JavaBeansTM example described in Chapters 1 - 3.

When the first RegistrationBean object is created, it creates one static instance of the JDCConnectionDriver class. This static driver object registers itself with the DriverManager in the JDCConnectionDriver constructor making it available for connection requests to all RegistrationBean objects created by the client application.

Passing the URL as jdbc:jdc:jdcpool in the getConnection method, lets the DriverManager match the getConnection request to the registered driver. The DriverManager uses simple String matching to find an available driver that can handle URLs in that format.

public class RegistrationBean implements EntityBean{

  private transient EntityContext ctx;
  public String theuser, password; 
  public String	creditcard, emailaddress;
  public double balance;

//Static class instantiation
  static {
        try{
        new pool.JDCConnectionDriver(
		"COM.cloudscape.core.JDBCDriver", 
		"jdbc:cloudscape:ejbdemo",
		"none", "none");
        }catch(Exception e){}
  }

  public Connection getConnection() 
                      throws SQLException{
        return DriverManager.getConnection(
				"jdbc:jdc:jdcpool");
  }
}

[TOP]


[ This page was updated: 13-Oct-99 ]

Products & APIs | Developer Connection | Docs & Training | Online Support
Community Discussion | Industry News | Solutions Marketplace | Case Studies
Glossary - Applets - Tutorial - Employment - Business & Licensing - Java Store - Java in the Real World
FAQ | Feedback | Map | A-Z Index
For more information on Java technology
and other software from Sun Microsystems, call:
(800) 786-7638
Outside the U.S. and Canada, dial your country's AT&T Direct Access Number first.
Sun Microsystems, Inc.
Copyright © 1995-99 Sun Microsystems, Inc.
All Rights Reserved. Legal Terms. Privacy Policy.