| CONTENTS | PREV | NEXT | INDEX | J2EE BluePrints |
Virtually all enterprise information systems are accessed via objects called connections. The following discussions provide pointers on efficient techniques for getting and managing connections.
A component is responsible for getting a connection to an enterprise information system. Once a connection to the enterprise information system is established, the component uses the connection to access enterprise information system resources. After the component is finished, it closes the connection.
The specific steps in establishing a connection to an enterprise information system are:
Code Example 6.1 illustrates how a component gets a connection to a relational database using the JDBC 2.0 API.
public void getConnection(...) {
// obtain the initial JNDI context
Context initctx = new InitialContext();
// Perform JNDI lookup to obtain factory
javax.sql.DataSource ds =
(javax.sql.DataSource)initctx.lookup(
"java:comp/env/jdbc/MyDatabase");
// Invoke factory to get a connection
java.sql.Connection cx = ds.getConnection();
// Use the Connection to access the resource manager
...
}
| Code Example 6.1 Establishing a Database Connection |
If each component were to acquire an enterprise information system connection and hold it until it gets removed, it would be difficult to scale up an application to support thousands of users. Since holding on to an enterprise information system connection across long-lived instances or transactions is expensive, components should manage connections more efficiently. To avoid scaling problems, almost every J2EE server should support connection pooling. However, an Application Component Provider still needs to follow sound connection management practices.
When an application is migrated from a two-tier structure to a multitier component-based structure, the issue of connection management becomes especially important. For example, a two-tier JDBC application may share a single connection across an entire application. After migration to a component-based partitioning, the application will need to deal with shared connections across multiple component instances.
This section provides guidelines for addressing application programming model issues related to connections using a JDBC connection to a relational database as an example.
6.8.2.1 Connection Life Cycle and Connection Pooling
A component can get a connection to a database in any client- or container-invoked method. We recommend that components open and close their connections within a single method, rather than holding connection state across methods. Only when the design of an application requires components to share connections across component instances or method invocations should connections be retained.
A component can retain a connection across methods at the cost of additional system resources and added programming model complexity required to manage the connection. One example might be a stateful session bean instance that retains the results of queries and database access operations across methods. The session bean gets a connection and starts a transaction through it. The transaction itself is handled internally by database with no external transaction management. Since the session bean wants to have this transaction span multiple methods, it must keep the connection open across method invocations.
Ideally, containers should take care of connection sharing. But currently the J2EE platform defines no standardized way of implementing connection sharing across different containers. Until a connection sharing mechanism is standardized for containers, a component can choose to do connection sharing through vendor-specific mechanisms offered by different containers and JDBC drivers. This comes at the cost of portability across containers.
6.8.2.2 Connection Management by Component Type
A J2EE application is typically composed of components of different types: JSP pages, servlets, and enterprise beans. These component types vary in terms of support for container-managed activation and passivation, execution of an instance for multiple clients, sharing of an instance across multiple clients, long-lived nature, and other factors. The Application Component Provider has to account for such differences across component types when deciding on a connection management model for an application. Here are a few examples that illustrate these differences.
A JSP page or servlet acquires and holds on to a JDBC connection in relation to the life cycle of its HTTP session. It can handle multiple HTTP requests across a single HTTP session from Web clients using the same JDBC connection.
A stateful session bean can share an open connection and its client-specific query results across multiple methods. However stateless session beans are designed to have no state specific to a client. So if stateless session beans share a connection across methods, they are required to maintain no client-specific state associated with the connection.
For entity beans, the EJB specification identifies methods that are allowed to perform enterprise information system access through a connection. These include ejbCreate, ejbPostCreate, ejbRemove, ejbFind, ejbActivate, ejbLoad, ejbStore, and business methods from the remote interface. An entity bean cannot access enterprise information systems from within the setEntityContext and unsetEntityContext methods because a container does not have a meaningful transaction or security context when they are called.
6.8.2.3 Multiple Connections
Some JDBC drivers don't support multiple concurrent connections under a single transaction. To be portable, components should avoid opening multiple concurrent connections to a single database. However, multiple component instances can access the same database using different connections.