The following sections are included in this chapter:
This chapter provides instructions for setting connection pool properties in order to optimize pooling behavior. Upon creation, UCP JDBC connection pools are pre-configured with a default setup. The default setup provides a general, all-purpose connection pool. However, different applications may have different database connection requirements and may want to modify the default behavior of the connection pool. Behaviors, such as pool size and connection timeouts can be configured and can improve overall connection pool performance as well as connection availability. In many cases, the best way to tune a connection pool for a specific application is to try different property combinations using different values until optimal performance and throughput is achieved.
Setting Connection Pool Properties
Connection pool properties are set either when getting a connection through a pool-enabled data source or when creating a connection pool using the connection pool manager.
The following example demonstrates setting connection pool properties though a pool-enabled data source:
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionPoolName("JDBC_UCP"); pds.setMinPoolSize(4);pds.setMaxPoolSize(20); ...
The following example demonstrates setting connection pool properties when creating a connection pool using the connection pool manager:
UniversalConnectionPoolManager mgr = UniversalConnectionPoolManagerImpl. getUniversalConnectionPoolManager(); pds.setConnectionPoolName("JDBC_UCP"); pds.setMinPoolSize(4);pds.setMaxPoolSize(20); ... mgr.createConnectionPool(pds);
Tip:
UCP JDBC connection pool properties may be set in any order and can be dynamically changed at runtime. For example,setMaxPoolSize
could be changed after the pool is created and the pool recognizes the new value and adapts accordingly.UCP JDBC connection pools include a set of properties that are used to control the size of the pool. The properties allow the number of connections in the pool to increase and decrease as demand increases and decreases. This dynamic behavior helps conserve system resources that are otherwise lost on maintaining unnecessary connections.
The initial pool size property specifies the number of available connections that are created when the connection pool is initially created or re-initialized. This property is typically used to reduce the ramp-up time incurred by priming the pool to its optimal size.
A value of 0
indicates that no connections are pre-created. The default value is 0
. The following example demonstrates configuring an initial pool size:
pds.setInitialPoolSize(5);
If the initial pool size property is greater than the maximum pool size property, then only the maximum number of connections are initialized.
If the initial pool size property is less than the minimum pool size property, then only the initial number of connections are initialized and maintained until enough connections are created to meet the minimum pool size value.
The minimum pool size property specifies the minimum amount of available and borrowed connections that a pool maintains. A connection pool always tries to return to the minimum pool size specified unless the minimum amount has yet to be reached. For example, if the minimum limit is set to 10
and only 2 connections are ever created and borrowed, then the number of connections maintained by the pool remains at 2
.
This property allows the number of connections in the pool to decrease as demand decreases. At the same time, the property ensures that system resources are not wasted on maintaining connections that are unnecessary.
The default value is 0
. The following example demonstrates configuring a minimum pool size:
pds.setMinPoolSize(2);
The maximum pool size property specifies the maximum number of available and borrowed (in use) connections that a pool maintains. If the maximum number of connections are borrowed, no connections will be available until a connection is returned to the pool.
This property allows the number of connections in the pool to increase as demand increases. At the same time, the property ensures that the pool doesn't grow to the point of exhausting a system's resources, which ultimately affects an application's performance and availability.
A value of 0
indicates that no connections are maintained by the pool. An attempt to get a connection results in an exception. The default value is to allow the pool to continue to create connections up to Integer.MAX_VALUE
(2147483647 by default). The following example demonstrates configuring a maximum pool size:
pds.setMaxPoolSize(100);
Stale connections are connections that remain either available or borrowed, but are no longer being used. Stale connections that remain borrowed may affect connection availability. In addition, stale connections may impact system resources that are otherwise wasted on maintaining unused connections for extended periods of time. The pool properties discussed in this section are used to control stale connections.
Note:
It is good practice to close all connections that are no longer required by an application. Closing connections helps minimize the number of stale connections that remain borrowed.The connection reuse feature allows connections to be gracefully closed and removed from a connection pool after a specific amount of time or after the connection has been used a specific number of times. This feature saves system resources that are otherwise wasted on maintaining unusable connections.
The maximum connection reuse time allows connections to be gracefully closed and removed from the pool after a connection has been in use for a specific amount of time. The timer for this property starts when a connection is physically created. Borrowed connections are closed only after they are returned to the pool and the reuse time has been exceeded.
This feature is typically used when a firewall exists between the pool tier and the database tier and is setup to block connections based on time restrictions. The blocked connections remain in the pool even though they are unusable. In such scenarios, the connection reuse time is set to a smaller value than the firewall timeout policy.
Note:
The maximum connection reuse time is different from the time-to-live connection timeout. The time-to-live connection timeout starts when a connection is borrowed from the pool; while, the maximum connection reuse time starts when the connection is physically created. In addition, with a time-to-live timeout, a connection is closed and returned to the pool for reuse if the timeout expires during the borrowed period. With maximum connection reuse time, a connection is closed and discarded from the pool after the timeout expires. See Setting the Time-To-Live Connection Timeout.The maximum connection reuse time value represents seconds. A value of 0
indicates that this feature is disabled. The default value is 0
. The following example demonstrates configuring a maximum connection reuse time:
pds.setMaxConnectionReuseTime(300);
The maximum connection reuse count allows connections to be gracefully closed and removed from the connection pool after a connection has been borrowed a specific number of times. This property is typically used to periodically recycle connections in order to eliminate issues such as memory leaks.
A value of 0
indicates that this feature is disabled. The default value is 0
. The following example demonstrates configuring a maximum connection reuse count:
pds.setMaxConnectionReuseCount(100);
The abandoned connection timeout enables borrowed connections to be reclaimed back into the connection pool after a connection has not been used for a specific amount of time. Abandonment is determined by monitoring calls to the database. This timeout feature helps maximize connection reuse and conserves system resources that are otherwise lost on maintaining borrowed connections that are no longer in use.
Note:
UCP for JDBC either cancels or rolls back connections that have local transactions pending before reclaiming connections for reuse.The abandoned connection timeout value represents seconds. A value of 0
indicates that the feature is disabled. The default value is set to 0
. The following example demonstrates configuring an abandoned connection timeout:
pds.setAbandonConnectionTimeout(10);
The time-to-live connection timeout enables borrowed connections to remain borrowed for a specific amount of time before the connection is reclaimed by the pool. This timeout feature helps maximize connection reuse and helps conserve systems resources that are otherwise lost on maintaining connections longer than their expected usage.
Note:
UCP for JDBC either cancels or rolls back connections that have local transactions pending before reclaiming connections for reuse.The time-to-live connection timeout value represents seconds. A value of 0
indicates that the feature is disabled. The default value is set to 0
. The following example demonstrates configuring a time-to-live connection timeout:
pds.setTimeToLiveConnectionTimeout(18000)
The connection wait timeout specifies how long an application request waits to obtain a connection if there are no longer any connections in the pool. A connection pool runs out of connections if all connections in the pool are being used (borrowed) and if the pool size has reached it's maximum connection capacity as specified by the maximum pool size property. The request receives an SQL exception if the timeout value is reached. The application can then retry getting a connection. This timeout feature improves overall application usability by minimizing the amount of time an application is blocked and provides the ability to implement a graceful recovery.
The connection wait timeout value represents seconds. A value of 0
indicates that the feature is disabled. The default value is set to 3
seconds. The following example demonstrates configuring a connection wait timeout:
pds.setConnectionWaitTimeout(10);
The inactive connection timeout specifies how long an available connection can remain idle before it is closed and removed from the pool. This timeout property is only applicable to available connections and does not affect borrowed connections. This property helps conserve resources that are otherwise lost on maintaining connections that are no longer being used. The inactive connection timeout (together with the maximum pool size) allows a connection pool to grow and shrink as application load changes.
The inactive connection timeout value represents seconds. A value of 0
indicates that the feature is disabled. The default value is set to 0
. The following example demonstrates configuring an inactive connection timeout:
pds.setInactiveConnectionTimeout(60);
The timeout check interval property controls how frequently the timeout properties (abandoned connection timeout, time-to-live connection timeout, and inactive connection timeout) are enforced. Connections that have timed-out are reclaimed when the timeout check cycle runs. This means that a connection may not actually be reclaimed by the pool at the moment that the connection times-out. The lag time between the connection timeout and actually reclaiming the connection may be considerable depending on the size of the timeout check interval.
The timeout check interval property represents seconds. The default value is set to 30
. The following example demonstrates configuring a property check interval:
pds.setTimoutCheckInterval(60);
The connection harvesting feature allows a specified number of borrowed connections to be reclaimed when the connection pool reaches a specified number of available connections. This feature helps ensure that a certain number of connections are always available in the pool and helps maximize performance. The feature is particularly useful if an application caches connection handles. Caching is typically performed for performance reasons because it minimizes re-initialization of state necessary for connections to participate in a transaction.
For example, a connection is borrowed from the pool, initialized with necessary session state, and then held in a context object. Holding connections in this manner may cause the connection pool to run out of available connections. The connection harvest feature reclaims the borrowed connections, if appropriate, and allows the connections to be reused.
Connection harvesting is controlled using the HarvestableConnection
interface and configured or enabled using two pool properties: Connection Harvest Trigger Count and Connection Harvest Maximum Count. The interface and properties are used together when implementing the connection harvest feature.
The setConnectionHarvestable(boolean)
method of the oracle.ucp.jdbc.HarvestableConnection
interface controls whether or not a connection will be harvested. This method is used as a locking mechanism when connection harvesting is enabled. For example, the method is set to false
on a connection when the connection is being used within a transaction and must not be harvested. After the transaction completes, the method is set to true
on the connection and the connection can be harvested if required.
Note:
All connections are harvestable, by default, when the connection harvest feature is enabled. If the feature is enabled, thesetConnectionHarvestable
method should always be used to explicitly control whether a connection is harvestable.The following example demonstrates using the setConnectionHarvestable
method to indicate that a connection is not harvestable when the connection harvest feature attempts to harvest connections:
Connection conn = pds.getConnection(); ((HarvestableConnection) conn).setConnectionHarvestable(false);
The connection harvest trigger count specifies the available connection threshold that triggers connection harvesting. For example, if the connection harvest trigger count is set to 10, then connection harvesting is triggered when the number of available connections in the pool drops to 10.
A value of Integer.MAX_VALUE
(2147483647 by default) indicates that connection harvesting is disabled. The default value is Integer.MAX_VALUE
.
The following example demonstrates enabling connection harvesting by configuring a connection harvest trigger count.
pds.setConnectionHarvestTriggerCount(2);
The connection harvest maximum count property specifies how many borrowed connections should be returned to the pool once the harvest trigger count has been reached. The number of connections actually harvested may be anywhere from 0 to the connection harvest maximum count value. Least recently used connections are harvested first which allows very active user sessions to keep their connections the most.
The harvest maximum count value can range from 0
to the maximum connection property value. The default value is 1
. An SQLException is thrown if an out-of-range value is specified.
The following example demonstrates configuring a connection harvest maximum count.
pds.setConnectionHarvestMaxCount(5);
Note:
If connection harvesting and abandoned connection timeout features are enabled at the same time, then the timeout processing does not reclaim the connections that are designated as nonharvestable.
If connection harvesting and time-to-live connection timeout features are enabled at the same time, then the timeout processing reclaims the connections that are designated as nonharvestable.
For more information about abandoned connection timeout feature and time-to-live connection timeout feature, refer to Chapter 6.
Statement caching makes working with statements more efficient. Statement caching improves performance by caching executable statements that are used repeatedly and makes it unnecessary for programmers to explicitly reuse prepared statements. Statement caching eliminates overhead due to repeated cursor creation, repeated statement parsing and creation and reduces overhead of communication between applications and the database. Statement caching and reuse is transparent to an application. Each statement cache is associated with a physical connection. That is, each physical connection will have its own statement cache.
The match criteria for cached statements are as follows:
The SQL string in the statement must be the same (case-sensitive) to one in the cache.
The statement type must be the same (prepared
or callable
) to the one in the cache.
The scrollable type of result sets produced by the statement must be the same (forward-only
or scrollable
) as the one in the cache.
Statement caching is implemented and enabled differently depending on the JDBC driver vendor. The instructions in this section are specific to Oracle's JDBC driver. Statement caching on other vendors' drivers can be configured by setting a connection property on a connection factory. See "Setting Connection Properties" for information on setting connection properties. In addition, refer to the JDBC vendor's documentation to determine whether statement caching is supported and if it can be set as a connection property. UCP for JDBC does support JDBC 4.0 (JDK16) APIs to enable statement pooling if a JDBC vendor supports it.
The maximum number of statements property specifies the number of statements to cache for each connection. The property only applies to the Oracle JDBC driver. If the property is not set, or if it is set to 0
, then statement caching is disabled. By default, statement caching is disabled. When statement caching is enabled, a statement cache is associated with each physical connection maintained by the connection pool. A single statement cache is not shared across all physical connections.
The following example demonstrates enabling statement caching:
pds.setMaxStatements(10);
Determining the Statement Cache Size
The cache size should be set to the number of distinct statements the application issues to the database. If the number of statements that an application issues to the database is unknown, use the JDBC performance metrics to assist with determining the statement cache size.
Statement Cache Size Resource Issues
Each connection is associated with its own statement cache. Statements held in a connection's statement cache may hold on to database resources. It is possible that the number of opened connections combined with the number of cached statements for each connection could exceed the limit of open cursors allowed for the database. This issue may be avoided by reducing the number of statements allowed in the cache, or by increasing the limit of open cursors allowed by the database.