hen building a large-scale J2EE/Java EE application, developers have a few options for establishing database (DB) connectivity from EJBs, including handling it transparently using a J2EE data source, or encapsulating JDBC details inside a Data Access Object (DAO) or inside a single class from which all session beans retrieve the DB connections. However, when using Oracle Containers for J2EE (OC4J), many enterprise Java developers establish a data-sources configuration through the EJB framework by using session beans with bean-managed persistence.
The problem with this approach, which establishes/retrieves a connection from the connection pool in the ejbCreate() method and releases it in ejbRemove(), is that when developers apply it to large applications with hundreds?or even thousands?of stateless session beans, database connections can get held up and eventually become stale (see Sidebar 1. Retaining a DB Connection Throughout a Stateless Session Bean’s Lifecycle). Consequently, when session beans try to process an application’s service request using a stale DB connection, the user sees unusual errors. They need to restart the application server to resolve the problem.
Oracle Application Server 10g Release 3 (10.1.3) addresses this challenge with the introduction of DB Connection Manager and OC4J’s implicit connection caching mechanism. This article details the features of this mechanism, which enables managed data source configuration, and its benefits to existing J2EE applications. While the discussion details using Oracle Application Server 10g, J2EE/Java EE-compliant app servers can also provide this feature by using the latest OC4J Oracle JDBC libraries.
Implicit Connection Caching to Keep Connections Fresh
Though connection caching (part of OC4J 9.0.3) and implicit connection caching (part of OC4J 10.1.3), which is also called connection pooling, are interchangeably used in technical discussions, they differ slightly. Both evolved from middle-tier connection management using data-sources. Connection caching, generally implemented in the middle tier, allows a single database connection to be shared among different applications.
When session beans request a database connection during ejbCreate(), the middle tier first looks in the pool for any available connections that would satisfy the request; if it finds them, the middle tier simply returns one of those connections. If the code releases the connection only during ejbRemove(), the connection is held up and eventually may become stale.
Implicit connection caching or connection pooling is a new JDBC 3.0-compliant connection cache implementation for data sources. The implicit connection cache is based on the concepts of physical and logical connections. The physical connections are the actual connections returned by the database, whereas the logical connections can be thought of as handles that the cache uses to manipulate the physical connections. Implicit connection cache uses the standard OracleDataSource APIs to get connections and services all connection requests from the connection cache after the underlying application enables caching.
Implementing implicit connection caching does not require any major changes to your existing application other than modifying the data-sources configuration, but it makes a big difference functionally. Session beans can still make the connection during ejbCreate(), but they are returned only as logical connections. Behind the scenes, OracleConnectionCacheManager ensures that the physical database connections are recycled and do not become stale.
Implicit Connection Caching in Action
While it is impractical to simulate a large-scale J2EE application’s behavior with sample code, the accompanying code demonstrates the use of implicit connection caching.
It uses OC4J10.1.3 and the latest managed data sources configuration parameters as follows:
The client application connects to the EJB and invokes the doDBService() method. The same client code can be made into a multi-threaded application to simulate the load. But be aware?it may stall your colleagues’ work.
New OC4J Configurable Parameters
Besides the standard parameters (maximum pool size, minimum pool size, maximum number of attempts, maximum period of time of inactivity, and maximum period of time to wait for a JDBC connection before time out), OC4J 10.1.3 offers various new configurable parameters, such as initial-limit, used-connection-wait-timeout, login-timeout, validate-connection, abandoned-connection-timeout, and validate-connection.
These parameters are self-explanatory, but two play a very important role in ensuring that DB connections never go stale: validate-connection and abandoned-connection-timeout. When set to true, validate-connection first validates the connection before giving it to the session bean. Similarly, abandoned-connection-timeout is explicitly applicable for logical connections. The connection manager monitors the database-execute calls issued by each DB connection and based on the inactive time, reclaims and recycles the connection.
OC4J 10.1.3’s implicit connection caching feature has configuration parameters for using all the latest features that are part of Oracle Real Application Clusters (RAC), a recent addition to the Oracle database. RAC prevents application outages from instance failures by having multiple nodes working in parallel with data backup, and Oracle Net Services provides load balancing for a cluster database. Balancing the application workload can provide better performance and can easily support more users by adding more nodes into the cluster.
If you are experiencing intermittent stale DB connections in your Oracle OC4J app server and an app server upgrade is in your plans, now is the time to do it.