Technical Note

Connection Caching in OC4J 10g 10.1.3 Data Sources

Author: Frances Zhao
Published: July 2004

One of the most time-consuming operations in deploying J2EE applications is establishing a connection to the database. Application servers commonly offer connection caching, or pooling, to minimize the overhead incurred for this task. (Although the terms "connection caching" and "pooling" have different meanings in JDBC, we will use the terms interchangeably here.)

In Oracle Application Server Containers for J2EE 10g (OC4J) 9.0.4, data sources employed different connection caching mechanisms, depending on the type of data sources. OC4J 10g 10.1.3, however, includes several key improvements in data sources, one of which is a new connection caching mechanism that is uniform across Oracle data sources and also offers integrated Real Application Clusters (RAC) failover support.  This mechanism leverages the new JDBC connection caching features from Oracle Database 10g. (Note: OC4J 10g 10.0.3 was recently reversioned to 10.1.3, and the next public release will reflect this change. All references to version 10.1.3 here are applicable to the currently available 10.0.3 release.)

This Technical Note offers a close look at this new feature, and illustrates how it is used in applications.

OC4J 10g 10.1.3 Data Sources: An Overview

OC4J 10g 10.1.3 has simplified the data source classification: now there are only two types of data sources: managed data source and native data source.

Managed data sources are data sources that are managed by OC4J.  Specifically, a managed data source is an OC4J-provided implementation of the java.sql.DataSource interface that acts as a wrapper to a JDBC driver or data source.  J2EE components access managed data sources via JNDI with no knowledge that the data source implementation is a wrapper. OC4J provides critical system infrastructure, such as global transaction management, connection caching, dynamic configuration via JMX, and error handling, for managed data sources.

Native data sources also implement the java.sql.DataSource interface, and are provided by JDBC-driver vendors such as Oracle and DataDirect. Native data sources are not wrapped by OC4J at all.

Key differences between managed and native data sources are summarized in the following table:

Managed Data Source Native Data Source
Connections retrieved from a data source can participate in global transactions Yes
No
Data source makes use of OC4J's connection pool and statement caches Yes No
Connection returned from a data source rapped with an OC4J Connection Proxy Yes No

Connection Caching

Connection caching, generally implemented in the middle tier, allows a single database connection to be shared among different applications.  The middle tier maintains a pool of pre-allocated physical database connections that applications can use to interact with database servers.  When applications request a database connection, the middle tier first looks in the pool to see if there are any available connections that would satisfy the request; if so, the middle tier simply returns one of those connections.

In a scenario where a connection is requested and the connection cache does not have any free-pooled connection instances, new pooled connection instances are created.  A "free" pooled connection instance is one that currently has no logical connection instances associated with it; in other words, it is a pooled connection instance whose physical connection is not being used.

When applications close the connections, the middle tier would send the connections back to the pool, thereby avoiding the resource-intensive task of opening a new database connection each time a connection request is made.

The pooled connections in the cache all have some connection properties or attributes (database name, server name, port number, and so on). Most connection caches consist of a pool of one or more connections to the same database for the same username.

Connection Caching in OC4J 10g 10.1.3 Data Sources

Connection caching in OC4J 10g 10.1.3 data sources leverages all of the new caching features provided by Oracle Database 10g JDBC—specifically, features in the new Implicit Connection Cache.

Prior to Oracle Database 10g, Oracle JDBC's connection cache interface was named OracleConnectionCache and its implementation was named OracleConnectionCacheImpl. The cache only supported pooling of physical connections to a particular database for a specified username. In Oracle 10g JDBC, the OracleConnectionCache interface and the OracleConnectionCacheImpl class are both deprecated, moving toward a more robust and performance-oriented architecture. The new architecture was designed so that connection caching can be transparently integrated into data sources.

Implicit Connection Cache is a new JDBC 3.0-compliant connection cache implementation for data sources.  It eliminates the need for application developers to write their own cache implementations by offering transparent access to the cache.  It also provides support for multiple users and the ability to request connections based on user-defined attributes.

The Implicit Connection Cache works on the concepts of physical and logical connections.  It uses the standard OracleDataSource APIs to get connections, and it services all connection requests from the connection cache after caching is enabled by the underlying application. The physical connections are the actual connections returned by the database, whereas the logical connections can be thought of as handles used by the cache to manipulate the physical connections.

Implicit connection caching also provides a new class, OracleConnectionCacheManager, so that applications can use its rich set of administrative APIs to create, manage, and maintain the connection caches in an efficient way. Applications can manage their cache either through the single OracleConnectionCacheManager instance, or through the OracleDataSource associated with the cache. These APIs are used extensively in OC4J 10g 10.1.3.

A callback mechanism is also provided for users to define cache behavior and determine the exact connections retrieved from the cache via the user-defined connection attributes.

The new connection caching mechanism also includes integrated RAC failover support for Oracle databases.  It provides the ability to failover connections in the connection cache as quickly and efficiently as the database itself, which is achieved by listening to the UP/DOWN RAC failover events generated by the database. The event publish/subscribe mechanism is provided by Oracle Notification Service(ONS). Such support only works for the RAC database, since it supports generation of the desired failover events.

Some of the advantages associated with the new connection caching in OC4J 10g 10.1.3 data sources include:
  • Driver independence
  • Transparent access to the connection cache
  • Multiple users and passwords per cache
  • Compliance to JDBC 3.0 standards
  • Connection recycling and refresh of stale connections
  • Attribute-based search for connections
  • Multiple cache enabled DataSource
  • Connection cache callback mechanism
  • Integrated support for RAC fast connection failover.
Applications can easily take advantage of the new connection caching functionality in OC4J 10g 10.1.3 data sources.  The application simply configures the data source along with its connection cache, gets a connection from that cache, uses that connection to carry out some business logic, and returns the connection to the cache after use. The application can also reinitialize some connection properties using the OracleConnectionCacheManager. Basically, applications would still use the data sources as they typically do, like data source setup and lookup.  In addition, applications would configure the connection caches that they wish to use. For most applications, this goal is achieved declaratively via simple configuration attribute changes on managed as well as native data sources. For native data sources provided by Oracle 10g JDBC, this can also occur programmatically by calling specific connection-cache management APIs.  Again, it is worth noting that these APIs are the very same APIs that OC4J uses in offering its own connection caching.

Configuring Connection Caches Declaratively

In OC4J 10g 10.1.3, specifying connection caching attributes is relatrively easy.  For most applications, such specification is done in the data-sources.xml configuration file declaratively.

Managed Data Source

For managed data sources, configuring connection caches can be done in two steps:

  1. Add a connection cache with the <connection-pool> XML element in data-sources.xml to specify the details of its desired attributes.
  2. Use the "connection-pool-name" attribute in each <managed-data-source> XML element in the same file to specify the name of the connection cache that this managed data source uses to pool its connections.

Step 2 is relatively simple, so let's focus only on Step 1.  The <connection-pool> element has the following attributes (each attribute is optional except when marked as 'Required'):

Attribute Name Description Default
name (Required) The name of the connection pool; must be unique
None
min-connections The minimum number of connections that the connection pool will maintain
0
max-connections The maximum number of connections that can be open at any given time; a value of 0 or less indicates that there is no maximum limit.
0
initial-limit
Sets the size of the connection cache when the cache is initially created or reinitialized. When this property is set to a value greater than 0, that many connections are pre-created and are ready for use. This property is typically used to reduce the "ramp-up" time in priming the cache to its optimal size.
0
used-connection-wait-timeout
The amount of time to wait (in seconds) for a used connection to be released by a client.  This attribute applies only when the maximum number of connections have been retrieved from the data source and are in use. In this case, when a client tries to borrow a connection from the pool and all connections are in use, the connection pool will wait for a connection to be released back to the pool.
60
inactivity-timeout
The amount of time (in seconds) that an unused connection is inactive before it is removed from the pool
60
login-timeout
The maximum amount of time (in seconds) that this data source will wait while attempting to connect to a database. A value of zero specifies that the timeout is the default system timeout if there is one; otherwise, it specifies that there is no timeout.
0
connection-retry-interval
The interval to wait (in seconds) before retrying a failed connection attempt; used in conjunction with "max-connnect-attempts"
1
max-connect-attempts
The number of times to retry making a connection; used in conjunction with "connection-retry-interval"
3
validate-connection Indicates whether a connection, when borrowed from the pool, will be validated against the database.  A value of "true" indicates that when a connection is borrowed from the connection pool, the statement, stated by "validate-connection-statement," is executed to verify that the connection is valid.  A value of "false" means that no statement will be executed when a connection is borrowed from the pool. Used in conjunction with "validate-connection-statement."
false
validate-connection-statement
The SQL statement to execute when a connection is borrowed from the pool; used in conjunction with "validate-connection"
None
num-cached-statements The maximum number of statements that should be cached for each connection.  Any value greater than 0 automatically enables statement caching for the data source.
0
time-to-live-timeout
The maximum time, in seconds, a used connection may be active. When this timeout expires, the used connection is unconditionally closed, the relevant statement handles are canceled, and the connection is returned to the connection pool.  A value of –1 means that the feature is not enabled.
-1
abandoned-connection-timeout
Oracle databases only.  Abandoned-connection-timeout is similar to the inactivity-timeout, but on a logical connection. When set, JDBC monitors SQL database activity on this logical connection (connection borrowed from the cache by the user). For example, when a stmt.execute() is invoked on this connection, a heart beat is registered to convey that this connection is active. The heart beats are monitored only at places (to lower the cost of monitoring), that result in database execute calls. If a connection has been inactive for the specified amount of time, the underlying PooledConnection is reclaimed and returned to the cache for reuse. The default value is -1, meaning, this feature is not in effect.
-1
disable-server-connection-pooling
Determines whether or not to disable the application server's connection pool.  This attribute is available because some JDBC drivers provide connection pooling inside the driver. When the JDBC driver is Oracle and the driver is using the Implicit Connection Cache, then this attribute will be ignored.
false
property-check-interval
Oracle databases only. The time interval (in seconds) for the cache daemon thread to enforce the time out limits.
900
lower-threshold-limit
Oracle databases only. The lower threshold limit on the connection pool. Defaults to 20% of the max-connections.
20%

In addition to the above attributes, each <connection-pool> element must contain one <connection-factory> element, which defines the connection factory used to create connections for the connection pool.  It has the following attributes (each attribute is optional except when marked as 'Required'):

Attribute Name Description Default
factory-class (Required) Defines the fully-pathed class of the connection-factory implementation.  It must be an implementation of java.sql.Driver, javax.sql.DataSource, javax.sql.ConnectionPoolDataSource, or javax.sql.XADataSource.
None
url (Required) The url to use to connect to the underlying database
None
user The default user to use to connect to the database
None
password
The default password to use to connect to the database
None
login-timeout
The maximum time (in seconds) to wait while attempting to connect to a database.  A value of zero specifies that the timeout is the default system timeout if there is one; otherwise, it specifies that there is no timeout.
0

Now let's look at some concrete examples:

Managed Data Source Using an XADataSource Connection Factory


<managed-data-source
 jndi-name="jdbc/ManagedXADS"
 description="Managed DataSource"
 connection-pool-name="myConnectionPool"
 name="ManagedXADS"/>

<connection-pool
 name="myConnectionPool"
 min-connections="10"
 max-connections="30"
 inactivity-timeout="30">
  <connection-factory 
   factory-class="oracle.jdbc.xa.client.OracleXADataSource"
   user="scott"
   password="tiger"
   url="jdbc:oracle:thin:@localhost:1521:oracle"/>
   <property name="nativeXA" value="true"/>
  </connection-factory>
</connection-pool>
        
Managed Data Source Using a DataSource Connection Factory <managed-data-source jndi-name="jdbc/ManagedDS"
description="Managed DataSource">
connection-pool-name="myConnectionPool"
name="ManagedDS"/>
<connection-pool name="myConnectionPool" min-connections="10" max-connections="30" inactivity-timeout="30"> <connection-factory factory-class="oracle.jdbc.pool.OracleDataSource" user="scott" password="tiger" url="jdbc:oracle:thin:@localhost:1521:oracle"/> <property name="loginTimeout" value="30"/> </connection-factory> </connection-pool>
Native Data Source

For native Oracle data sources, configuring connection caches is primarily done programmatically. (See the following section for more details.)  Declarative configuring of connection caches can also be done in two steps:

  1. Use "oracle.jdbc.pool.OracleDataSource" as the value for the "data-source-class" attribute in each <native-data-source> XML element in data-sources.xml. This is the data source implementation in the Oracle 10g JDBC drivers that comes with implicit connection caching.
  2. Specify in the <property> elements within <native-data-source> any cache-specific properties to control the connection cache's behavior.
For Step 2, the following property names can be used in the <property> element's specifications:

Name Type Description
connectionCacheName String Name of cache; cannot be changed after cache has been created.
connectionCachingEnabled Boolean Whether Implicit Connection Caching is enabled
fastConnectionFailoverEnabled Boolean Whether RAC Fast Connection Failover is enabled

Here's a concrete example:

<native-data-source
 name="nativeDataSource"
 jndi-name="jdbc/nativeDS"
 description="Native DataSource"
 data-source-class="oracle.jdbc.pool.OracleDataSource"
 user="scott"
 password="tiger"
 url="jdbc:oracle:thin:@localhost:1521:oracle">
  <property name="connectionCacheName" value="ICC1"/>
  <property name="connectionCachingEnabled" value="true"/>
  <property name="fastConnectionFailoverEnabled" value="false"/>
</native-data-source>
Configuring Connection Caches Programmatically

Managed Data Source

When using managed data sources, connection caching is specified declaratively via the data source configuration files.  This was explained in detail in "Configuring Connection Caches Declaratively."

Native Data Source

For native data sources provided by Oracle 10g JDBC, applications have the additional option to configure connection caching programmatically. Because caching is uniform across Oracle data sources in OC4J 10g 10.1.3, this is not much more difficult than the declarative approach.  With this option, applications further have two ways to take advantage of connection caching: (1) rely on the implicit connection caching behavior in OracleDataSource and set the connection cache properties on the data source, or (2) directly use the connection cache manager OracleConnectionCacheManager APIs.

For (1), the OracleDataSource class provides the following setter() and getter() methods for connection caching properties:
  • String getConnectionCacheName()
  • void setConnectionCacheName(String cacheName)
  • java.util.Properties getConnectionCacheProperties()
  • void setConnectionCacheProperties(java.util.Properties cp)
Each of the connection cache property here corresponds to one configuration attribute in the managed data source case in "Configuring Connection Caches Declaratively," although the exact property name may differ slightly.

Resources

OC4J 10g 10.0.3 Developer Preview 2
OC4J 10g (10.0.3) Developer Preview 2 has passed the J2EE 1.4 compatibility test suite and is officially J2EE 1.4 compatible. For testing and development only!

Oracle 10g JDBC Drivers
The JDBC Thin, OCI, and server-side internal drivers have been completely restructured to improve performance in Oracle 10g JDBC. Includes JDBC 3.0 and J2EE 1.3 standards features support.

Oracle 10g JDBC Sample Code
The Oracle 10g JDBC Samples demonstrate the use of various new features introduced in the JDBC 3.0 specification.

Oracle Database 10g JDBC Developer's Guide and Reference
Oracle Database JDBC Developer's Guide and Reference is intended for developers of JDBC-based applications and applets.

Keep Your Connections: Using Implicit Connection Cache for Transparent Cache Access, by Kuassi Mensah

For (2), the OracleConnectionManager provides administrative APIs that applications can use to manage available connection caches.  Following is a list of some APIs. (For more detailed information on both (1) and (2), please refer to the Oracle Database 10g JDBC Developer's Guide and Reference.)
  • static OracleConnectionCacheManager getCacheManagerInstance()
  • void createCache(String cacheName, javax.sql.DataSource ds, Properties cacheProperties)
  • String createCache(javax.sql.DataSource ds, Properties cacheProperties)
  • void removeCache(String cacheName, int mode)
  • void refreshCache(String cacheName, int mode)
  • java.util.properties getCacheProperties(String cacheName)
The following configureDataSource method shows the ordinary setup of OracleDataSource that is associated with the cache. It configures the Datasource with appropriate values of host name, user name, password, and so on. It also loads some connection properties that are are stored in the Connection.properties file:
private void configDataSource(OracleDataSource ods) {
......
/* Load the properties file to get the connection properties  
 * from the Connection.properties file
 */
Properties prop = this.loadParams("Connection"); 
ods.setDriverType("thin");
ods.setHostName("localhost");
ods.setNetworkProtocol("tcp");
ods.setPortNumber(1521);
ods.setUser("scott");
ods.setPassword("tiger");
ods.setServiceName("oracle");
ods.setConnectionProperties(prop);
......
}   
The following code illustrates the approach (1) above.  The method configCachingInDataSource enables the connection caching and also sets the cache name, which uniquely identifies the connection cache. It then sets some connection cache properties on the OracleDataSource, which will be passed on to the cache.
private void configCachingInDataSource(OracleDataSource ods)
  throws SQLException
{
  ......
  ods.setConnectionCachingEnabled(true);  // Enable caching
  ods.setConnectionCacheName(CACHE_NAME); // Set the cache name   

  Properties cacheProperties = new Properties();

  cacheProperties.setProperty("MinLimit", "1");  // Set Min Limit for the Cache 
  cacheProperties.setProperty("MaxLimit", "15"); // Set Max Limit for the Cache  
  cacheProperties.setProperty("InitialLimit", "10");   // Set the Initial Limit  

  ods.setConnectionCacheProperties(cacheProperties);

}
The following code illustrates the approach (2) above: how a connection cache is created using the OracleConnectionCacheManager.  The createCache method is used to create the cache, while taking the OracleDataSource cache name and the cache Properties objects.  Note that the connection cache properties are set while creating the connection cache:
private void initializeConnectionCache() throws Exception {
  .............. 
 
  OracleDataSource ods = new OracleDataSource();

  this.configureDataSource(ods);
  ods.setConnectionCachingEnabled(true);  // Enable caching

  // Initialize the Connection Cache
  OracleConnectionCacheManager connMgr =
    OracleConnectionCacheManager.getConnectionCacheManagerInstance();
  
  /* This object holds the properties of a cache and is passed to the 
   * ConnectionCacheManager while creating the cache.
   */
  Properties cacheProperties = new Properties();

  cacheProperties.setProperty("MinLimit", "1");   // Set Min Limit for the Cache 
  cacheProperties.setProperty("MaxLimit", "15");  // Set Max Limit for the Cache 
  cacheProperties.setProperty("InitialLimit", "10");    // Set the Initial Limit  

  /* Create the cache by passing the cache name, data source and the 
   * cache properties 
   */
  connMgr.createCache(CACHE_NAME, ods, properties);
Summary

Database connection cache is a powerful part of the Oracle Application Server. With simplified data source configuration and integrated connection cache management from Oracle Database 10g, OC4J 10g 10.1.3 provides a scalable platform for building distributed J2EE applications.

E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy