Skip to main content

Connection pools

Dive into connection pooling with J2EE

Siva Visveswaran, columnist, JavaWorld
Siva Visveswaran has been working with Java technology for more than three years and has been smitten by J2EE. Most recently, he has been involved in architecture and development of large and complex J2EE applications for Fortune 100 financial service companies and dot-coms. He has more than 12 years experience in the IT industry and is currently working as a principal consultant at a large management consulting firm, specializing in e-business architecture, infrastructure technologies, and content management solutions. Siva has a master's degree in computer science from Wayne State University in Detroit, Mich. You can contact him at siva.visveswaran@javaworld.com.

Summary:  Reprinted with permission from JavaWorld.

Connection pooling is a technique used for sharing server resources among requesting clients. This article focuses on support for connection pooling of both database resources and non-database resources in a J2EE environment. Siva examines the JDBC 2.0, JMS 1.02, JNDI 1.2 Standard Extension APIs with regard to connection pooling and looks at some existing vendor implementations of those APIs. He then looks at the upcoming J2EE Connector Architecture 1.0 that would support a vendor-independent/pluggable approach to managing resource connections.

Date:  21 Nov 2000
Level:  Introductory
Activity:  513890 views

The Java 2 Enterprise Edition (J2EE) specification provides a distributed services-based architecture for implementing highly scalable, reliable, and available e-business applications. In general, a J2EE application architecture maps to the Model-View-Controller (MVC) framework -- repositories/external system resources support the domain model (Model), JSPs/Servlets manage the presentation (View), and EJBs deal with the business logic (Controller).

A typical e-business application use case would be realized by components in all the three layers on the server side. Given the large number of user interactions (millions for customer-facing applications), the finite server-side resources need to be optimally shared. Such resources may include databases, message queues, directories, enterprise systems (SAP, CICS), and so forth, each of which is accessed by an application using a connection object that represents the resource entry point. Managing access to those shared resources is essential for meeting the high-performance requirements for J2EE applications.

Connection pooling is a technique that was pioneered by database vendors to allow multiple clients to share a cached set of connection objects that provide access to a database resource. In this article, I examine connection pooling in a J2EE environment for server-side resources such as databases, message queues, directories, and enterprise systems.

Why pool resource connections?

Consider this code example where an EJB accesses a database resource using JDBC 1.0, without connection pooling.


EJB accesses a database resource using JDBC 1.0, without connection pooling

...
  import java.sql.*;
  import javax.sql.*;
  ...
  public class AccountBean implements EntityBean {
  ...
  public Collection ejbFindByLastName(String lName) {
     try {
           String dbdriver =  new InitialContext().lookup("java:comp/env/DBDRIVER").toString();
           Class.forName(dbdriver).newInstance();
           Connection conn = null;
           conn = DriverManager.getConnection("java:comp/env/DBURL", "userID", "password");
           ...
           conn.close();
        }
  ...
  }
  

Evidently, the main problem in this example is the opening and closing of connections. Given that entity beans are shared components, for every client request, the database connections are acquired and released several times.

You can see from Figure 1 that acquiring and releasing database connections via the database manager, using JDBC 1.0, will impact the performance on the EJB layer. That impact is due to the overhead in creating and destroying those objects by the database resource manager process. Typically, the application server process takes around one to three seconds to establish a database connection (that includes communicating with the server, authenticating, and so forth), and that needs to be done for every client (EJB) request.


Figure 1. Connection management using JDBC 1.0


Connection pooling using service provider facilities

Now I will look at what connection pooling facilities are currently available for database and non-database resource types in the J2EE environment.

JDBC 2.0 Standard Extension API The JDBC 2.0 Standard Extension API specifies that a database service provider can implement a pooling technique that can allow multiple connection objects from a resource pool to be shared transparently among the requesting clients. In that situation, a J2EE component can use connection objects without causing overheads on the database resource manager, since a pool manager creates the connection objects up front, at startup. The application service provider implements the pool manager in its memory space and can optimize resource usage by dynamically altering the pool size, based on demand. That is illustrated in Figure 2.


Figure 2. Connection pooling using JDBC 2.0 Standard extension

Using the DataSource interface (JDBC 2.0) or the DriverManager (JDBC 1.0) interface, a J2EE component could get physical database connection objects. To obtain logical (pooled) connections, the J2EE component must use these JDBC 2.0 pooling manager interfaces:

  • A javax.sql.ConnectionPoolDataSource interface that serves as a resource manager connection factory for pooled java.sql.Connection objects. Each database server vendor provides the implementation for that interface (for example, Oracle implements the oracle.jdbc.pool.OracleConnectionPoolDataSource class).
  • A javax.sql.PooledConnection interface that encapsulates the physical connection to a database. Again, the database vendor provides the implementation.

An XA (X/Open specification) equivalent exists for each of those interfaces as well as for XA connections.

The following code example shows how an EJB application might access a database resource by using pooled connection objects (based on JDBC 2.0). The EJB component in this example uses a JNDI lookup to locate the database connection pool resource. The JNDI 1.2 Standard Extension API lets Java applications access objects in disparate directories and naming systems in a common way. Using the JNDI API, an application can look up a directory to locate any type of resource such as database servers, LDAP servers, print servers, message servers, file servers, and so forth.

Note: The code will vary depending on the database vendor implementation classes:


An EJB application accesses a database resource by using pooled connection objects

import java.sql.*; 
  import javax.sql.*; 
  // import here vendor specific JDBC drivers
  public ProductPK ejbCreate() {
        try {
  // initialize JNDI lookup parameters
              Context ctx = new InitialContext(parms);
  ...
              ConnectionPoolDataSource cpds = (ConnectionPoolDataSource)ctx.lookup(cpsource); 
  ... 
  // Following parms could all come from a JNDI look-up 
              cpds.setDatabaseName("PTDB"); 
              cpds.setUserIF("XYZ"); 
  ...
              PooledConnection pc = cpds.getPooledConnection(); 
              Connection conn = pc.getConnection(); 
  ...
  // do business logic
              conn.close();
        }
  ...
  }  
  

The key difference between the above code (using JDBC 2.0) and using JDBC 1.0 is that a getConnection() gets an already open connection from the pool, and close() simply releases the connection object back to the pool. JDBC 2.0 drivers are available today from almost every database server vendor such as Oracle, DB2, Sybase, and Informix. And most application server vendors (IBM, BEA, iPlanet, IONA, etc.) today support JDBC 2.0.

I should note that today almost all application servers employ a two-tier connection pooling architecture where the pools are held in the application server memory space (as opposed to a stand-alone connection broker).

JMS 1.02 Standard Extension API
J2EE application components can communicate asynchronously with other enterprise applications using a messaging resource. The JMS 1.02 Standard Extension API provides a vendor-independent way to communicate with messaging service providers. As in the case of a database resource, message queues are accessed using connection objects that can be pooled.

The JMS 1.02 API includes the following interfaces to support resource pooling:

  • A javax.jms.QueueConnectionFactory or javax.jms.TopicConnectionFactory for factory objects
  • A javax.jms.QueueConnection or javax.jms.TopicConnection for connection objects

A JMS service provider implements those interfaces. This code sample shows how an EJB component might access a message queue resource, using connection objects.


An EJB component accesses a message queue resource, using connection objects

// Use JNDI to find the connection factory and the destination 

  Context ctx = new InitialContext(); 
  QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("java:comp/env/jms/theFactory");
  Queue queue = (Queue) ctx.lookup("java:comp/env/jms/theQueue"); 

  // create a connection, session, sender, and the message QueueConnection conn; 
  QueueConnection conn = factory.createQueueConnection("myUserName", "myPassword"); 
  QueueSession session = connection.createQueueSession (false, Session.AUTO_ACKNOWLEDGE); 
  QueueSender sender = session.createSender(queue); 
  ...
  // start up the connection, send the message 
  connection.start(); 
  sender.send("Message"); 
  connection.stop(); 

  // now close all resources to ensure that native resources are released 
  sender.close(); 
  session.close(); 
  connection.close();
  

With connection pooling, the JMS factory classes typically have proxies (configured by an administrator) so the open() and close() requests actually go to the proxies that manage a connection pool. Following the JMS API guidelines, a JMS service provider may implement a database to manage the message queues. In that situation, the appropriate JDBC driver renders the connection pooling. If the application is already using a JDBC 2.0 connection pool-enabled database, then all you need to do is configure the JNDI property for the JMS to use that JDBC instance.

JNDI API for LDAP
The javax.naming.LDAP package includes classes that are specific to LDAP (and not included in the generic javax.naming.directory). Unlike the JDBC 2.0 and JMS 1.02 APIs, the JNDI LDAP API does not specify any interfaces for connection pooling. A directory service provider could optionally provide support via SDKs. For example, iPlanet's Netscape Directory Server SDK 4.0 for Java includes the following class for building LDAP clients:



public class netscape.ldap.util.ConnectionPool extends java.lang.Object
methods: Connection(), getConnection(), close(), etc. 

Refer to the "Netscape Directory Server Application Programmer's Guide" for more details (see Resources).


The J2EE Connector Architecture 1.0

In all of the above examples, the EJB components have to import vendor-specific implementation classes in order to use the connection pooling facilities of the resource. That obviously makes the EJBs less portable, weakening the J2EE promise.

Ideally, one would like a generic connection interface that EJBs can use for any resource type and all connection management functions, including pooling, provided under the hood. That is one of the goals of the upcoming J2EE Connector Architecture 1.0 specification; a draft copy is publicly available at the time of this writing (see Resources).

Figure 3 shows the central concept behind the architecture, the resource adapter. A pluggable component for each resource type supported by the application server, a resource adapter executes within the application server address space. The client API for accessing those adapters could either be the Common Client Interface (CCI) or (for backward compatibility) a resource-specific API such as JDBC 2.0. For instance, the CCI defines javax.resource.cci.ConnectionFactory and javax.resource.cci.Connection as interfaces for a connection factory and a connection respectively -- similar to the JDBC 2.0 interfaces I mentioned in the previous section.


Figure 3. Resource adapter in J2EE Connector Architecture 1.0

Connection pooling in Connector 1.0
The programming model for Connector 1.0 is as follows:

  • An EJB performs a JNDI lookup of a connection factory and then issues a getConnection() request.
  • The connection factory delegates the request to a ConnectionManager.
  • The connection manager looks for an instance of a connection pool in the application server. If no connection pool is available, then the manager uses the ManagedConnectionFactory to create a physical (nonpooled) connection.

    In that scenario, the resource adapter provider is assumed to implement the interface. However, the connector architecture does not indicate how an application server might implement a connection pool but provides guidelines, such as partitioning a pool based on adapter type, quality-of-service (QoS) requirements, and so forth. For more details, refer to the J2EE Connector Architecture specification (see Resources).

For example, the iPlanet Unified Integration Framework Toolkit v 6.0, a product version of Sun's connectors to enterprise/legacy systems based on the upcoming EJB 2.0 connector architecture, defines connection pools for each backend system that an EJB layer might access. A thread, executed periodically, monitors the use and longevity of pool objects. For details, refer to iPlanet Unified Integration Framework (see Resources).


Design considerations for the EJB layer

The fact that you have resource managers that manage your connection pools does not guarantee optimum performance from the EJB layer -- there are some design considerations as well!

First, consider the code example below of an EJB client accessing an LDAP directory that implements a connection pool.



import netscape.ldap.util.*; 
...
public class NewCustomerBean implements SessionBean {
...
      private SessionContext context;  // Bean Context
      private LDAPConnection lc; // LDAP Connection object
...
      public void setSessionContext(SessionContext sc) {
            this.context = sc;
// initialize JNDI lookup parameters
      Context ctx = new InitialContext(parms);
...
      ConnectionPool cp = (ConnectionPool)ctx.lookup(cpsource);
      // Establish LDAP Connection.
      try {
         this.lc = cp.getConnection();
...
      }

What is wrong with the above picture? First, the stateful session object (NewCustomerBean) opens up the connection object in the setEntityContext and holds on to it until the end of the use case -- a rather costly implementation if the number of users (sessions) increases rapidly. Second, and more important, since connection objects are not serializable, per the EJB 1.2 specification, the container can discard the bean instance upon passivation (i.e., move the session bean from its active state to a bean instance pool).

One alternative is that resource connections are acquired and released in the ejbActivate() and ejbPassivate() methods of the session bean, respectively. Without connection pooling, that is of course expensive and not recommended. With pooling however, connections can be acquired and released with minimum overhead for the EJB layer, using that technique. The point here is that beyond the facilities offered by the specifications and the implementations, design choices are, as always, key performance determinants.

A second consideration is around the issue of authentication. You might have observed that pooled connections imply shared connections, which then imply that the connections are not tied to a specific authentication credential. For example, in the case of JDBC 2.0 connections, an application server pool manager requests, at startup, a preset number of connections from the DB manager, using a single authentication credential (typically a userid/password) stored in a configuration file. Sometimes that may not satisfy the security policy for the application. The same argument applies for LDAP connections that require binding with a specific credential to an LDAP subtree. In those situations, one alternative might be to use a cached connection that has been established using a specific credential, which can be reused for the same type of credentials. The downside to that is that cached connections are held for long periods of time. Another alternative might be to use generic connections for resources and implement certain application-level security.


Conclusion

In this article, I showed the need for connection pooling resources in a J2EE environment, based on the shared nature of the resources as well as the EJB components that access them. You saw the facilities defined by the JDBC 2.0, JMS 1.02, and the JNDI 1.2 Standard Extension APIs as well as vendor support for the implementation of those API interfaces. Although the vendor-specific solutions are robust, you use them at the cost of EJB portability. The upcoming J2EE Connector Architecture 1.0 addresses that issue and makes resources pluggable, relieving the EJB layer from dealing with vendor-specific libraries. And finally, I explained why your design plays an important role in taking advantage of those pooling techniques for delivering high-performance J2EE applications.


Resources

About the author

Siva Visveswaran has been working with Java technology for more than three years and has been smitten by J2EE. Most recently, he has been involved in architecture and development of large and complex J2EE applications for Fortune 100 financial service companies and dot-coms. He has more than 12 years experience in the IT industry and is currently working as a principal consultant at a large management consulting firm, specializing in e-business architecture, infrastructure technologies, and content management solutions. Siva has a master's degree in computer science from Wayne State University in Detroit, Mich. You can contact him at siva.visveswaran@javaworld.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=10488
ArticleTitle=Connection pools
publish-date=11212000
author1-email=
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers