41 Tuning Application Module Pools and Connection Pools

This chapter describes how ADF Business Components application module pools work and how you can tune both application module pools and database connection pools to optimize application performance.

This chapter includes the following sections:

41.1 Introduction to Application Module Pooling

An application module pool is a collection application module instances of the same type. For example, the Fusion Order Demo application has one or more instances of the application module in it, based on the number of users that are visiting the site. This pool of application module instances is shared by multiple browser clients whose typical "think time" between submitting web pages allows optimizing the number of application module components to be effectively smaller than the total number of active users working on the system. That is, twenty users visiting the web site from their browser might be able to be serviced by 5 or 10 application module instances instead of having as many application module instances as you have browser users.

Application module components can be used to support Fusion web application scenarios that are completely stateless, or they can be used to support a unit of work that spans multiple browser pages. As a performance optimization, when an instance of an application module is returned to the pool in "managed state" mode, the pool tracks session references to the application module. The application module instance is still in the pool and available for use, but it would prefer to be used by the same session that was using it the last time because maintaining this so-called "session affinity" improves performance.

So, at any one moment in time, the instances of application modules in the pool are logically partitioned into three groups, reflecting their state:

  • Unconditionally available for use

  • Available for use, but referenced for session affinity reuse by an active user session

  • Unavailable, inasmuch as it's currently in use (at that very moment) by some thread in the web container.

Section 41.2.5, "What You May Need to Know About Configuration Property Scopes" describes the application module pool configuration parameters and how they affect the behavior of the pool.

41.1.1 Types of Pools Created When Running the Fusion Web Application

There are two kinds of pools in use when running a typical Fusion web application, Application Module pools and database connection pools. It's important to understand how many of each kind of pool your application will create.

41.1.1.1 Application Module Pools

Application Module components can be used at runtime in two ways:

  • As an application module the client accesses directly

  • As a reusable component aggregated (or "nested") inside of another application module instance

When a client accesses it directly, an application module is called a root application module. Clients access nested application modules indirectly as a part of their containing application module instance. It's possible, but not common, to use the same application module at runtime in both ways. The important point is that ADF only creates an application module pool for a root application module.

The basic rule is that one application module pool is created for each root application module used by a Fusion web application in each Java VM where a root application module of that type is used by the ADF controller layer.

41.1.1.2 Database Connection Pools

The type of database connection pool the Fusion web application uses depends on the connection type that you configure for your application modules:

  • JDBC URL (e.g. jdbc:oracle:thin:@penguin:1521:ORCL)

  • JNDI name for a data source (e.g. java:comp/env/jdbc/YourConnectionDS)

If you supply a JDBC URL connection while configuring your application module — which happens when you select a JDeveloper named connection which encapsulates the JDBC URL and username information — then the ADF database connection pool will be used for managing the connection pool.

If you supply the JNDI name of a JDBC data source then the ADF database connection pool will not be used and the configuration parameters described below relating to the ADF database connection pool are not relevant.

Note:

To configure the database connection pool for JDBC data sources looked-up by JNDI from your Java EE web and/or EJB container, consult the documentation for your Java EE container to understand the pooling configuration options and how to set them.

When using ADF database connection pooling, you have the following basic rule: One database connection pool is created for each unique <JDBCURL,Username> pair, in each Java VM where a <JDBCURL,Username> connection is requested by a root application used by the ADF controller layer.

41.1.2 Understanding Application Module and Connection Pools

The number of pools and the type of pools that your application will utilize will depend upon how the target platform is configured. For example, will there be more than one Java Virtual Machine (JVM) available to service the web requests coming from your application users and will there be more than one Oracle Application Server instance? To understand how many pools of which kinds are created for an application in both a single-JVM scenario and a multiple-JVM runtime scenario, review the following assumptions:

  • Your Fusion web application makes use of two application modules HRModule and PayablesModule.

  • You have a CommonLOVModule containing a set of commonly used view objects to support list of values in your application, and that both HRModule and PayablesModule aggregate a nested instance of CommonLOVModule to access the common LOV view objects it contains.

  • You have configured both HRModule and PayablesModule to use the same JDeveloper connection definition named appuser.

  • In both HRModule and PayablesModule you have configured jbo.passivationstore=database (the default) and configured the ADF "internal connection" (jbo.server.internal_connection) used for state management persistence to have the value of a fully-qualified JDBC URL that points to a different username than the appuser connection does.

41.1.2.1 Single Oracle Application Server Instance, Single Oracle WebLogic Server Instance, Single JVM

If you deploy this application to a single Oracle Application Server instance, configured with a single Oracle WebLogic Server instance having a single Java VM, there is only a single Java VM available to service the web requests coming from your application users.

Assuming that all the users are making use of web pages that access both the HRModule and the PayablesModule, this will give:

  • One application module pool for the HRModule root application module

  • One application module pool for the PayablesModule root application module

  • One DB connection pool for the appuser connection

  • One DB connection pool for the JDBC URL supplied for the internal connection for state management.

This gives a total of two application module pools and two database pools in this single Java VM.

Note:

There is no separate application module pool for the nested instances of the reusable CommonLOVModule. Instances of CommonLOVModule are wrapped by instances of HRModule and PayablesModule in their respective application module pools.

41.1.2.2 Multiple Oracle Application Server Instances, Single Oracle WebLogic Server Instance, Multiple JVMs

Next consider a deployment environment involving multiple Java VMs. Assume that you have installed Oracle Application Server onto two different physical machines, with a hardware load-balancer in front of it. On each of these two machines, imagine that the Oracle Application Server instance is configured to have one Oracle WebLogic Server instance with two JVMs. As users of your application access the application, their requests are shared across these two Oracle Application Server instances, and within each Oracle Application Server instance, across the two JVMs that its Oracle WebLogic Server instance has available.

Again assuming that all the users are making use of web pages that access both the HRModule and the PayablesModule, this will give:

  • Four application module pools for HRModule, one in each of four JVMs.

    (1 HRModule root application module) x (2 Oracle Application Server Instances) x (2 Oracle WebLogic Server JVMs each)

  • Four application module pools for PayablesModule, one in each of four JVMs.

    (1 PayablesModule root application module) x (2 Oracle Application Server Instances) x (2 Oracle WebLogic Server JVMs each)

  • Four DB connection pools for appuser, one in each of four JVMs.

    (1 appuser DB connection pool) x (2 Oracle Application Server Instances) x (2 Oracle WebLogic Server JVMs each)

  • Four DB connection pools for the internal connection JDBC URL, one in each of four JVMs.

    (1 internal connection JDBC URL DB connection pool) x (2 Oracle Application Server Instances) x (2 Oracle WebLogic Server JVMs each)

This gives a total of eight application module pools and eight DB connection pools spread across four JVMs.

As you begin to explore the configuration parameters for the application module pools in Section 41.2.7, "What You May Need to Know About Application Module Pool Parameters," keep in mind that the parameters apply to a given application module pool for a given application module in a single JVM.

As the load balancing spreads user requests across the multiple JVMs where ADF is running, each individual application module pool in each JVM will have to support one n th of the user load — where n is the number of JVMs available to service those user requests. The appropriate values of the application module and DB connection pools need to be set with the number of Java VMs in mind. The basic approach is to base sizing parameters on load testing and the results of the application module pooling statistics, then divide that total number by the n number of pools you will have based on your use of multiple application servers and multiple Oracle WebLogic Server instances. For example, if you decide to set the minimum number of application modules in the pool to ten and you end up with five pools due to having five Oracle WebLogic Server instances servicing this application, then you would want to configure the parameter to 2 (ten divided by five), not 10 (which would only serve a given application module in a single JVM).

41.2 Setting Pool Configuration Parameters

You control the runtime behavior of an application module pool by setting appropriate configuration parameters. You can set these declaratively in an application module configuration, supply them as Java System parameters, or set them programmatically at runtime.

41.2.1 How to Set Configuration Properties Declaratively

The Pooling and Scalability tab of the Edit Business Components Configuration dialog shown in Figure 41-1 is used for viewing and setting parameters.

Figure 41-1 Pooling and Scalability Tab of the Configuration Manager

Pooling and Scalability tab

41.2.2 What Happens When You Set Configuration Properties Declaratively

The values that you supply through the Configuration Manager are saved in an XML file named bc4j.xcfg in the ./common subdirectory relative to the application module's XML component definition. All of the configurations for all of the application modules in a single Java package are saved in that same file.

For example, if you look at the bc4j.xcfg file in the .src/oracle/fodemo/storefront/store/service/common directory of the Fusion Order Demo application's StoreFront project, you will see the three named configurations for its StoreServiceAM application module, as shown in Example 41-1. In this case, The StoreServiceAMLocal and the StoreServiceAMShared configurations uses JDBC URL connections for use by the Business Component Browser. The StoreFrontService uses JDBC data source names and is used by the Fusion web application. The connection details for each JDBC connection appear in the connections.xml file located in the ./.adf/META-INF subdirectory relative to the project directory.

Example 41-1 Configuration Settings for the StoreService Application Module

<BC4JConfig version="11.1" xmlns="http://xmlns.oracle.com/bc4j/configuration">
   <AppModuleConfigBag ApplicationName="oracle.fodemo.storefront.store.service.StoreServiceAM">
      <AppModuleConfig 
             DeployPlatform="LOCAL" 
             JDBCName="FOD" 
             jbo.project="StoreFrontService"
             name="StoreServiceAMLocal"
             ApplicationName="oracle.fodemo.storefront.store.service.StoreServiceAM">
         <Database jbo.locking.mode="optimistic"/>
         <Security AppModuleJndiName="oracle.fodemo.storefront.store.service.StoreServiceAM"/>
      </AppModuleConfig>
      <AppModuleConfig 
               DeployPlatform="LOCAL" 
               JDBCName="FOD"
               jbo.project="StoreFrontService" 
               name="StoreServiceAMLocalWeb" 
               ApplicationName="oracle.fodemo.storefront.store.service.StoreServiceAM">
         <AM-Pooling jbo.ampool.initpoolsize="1"/>
         <Database jbo.locking.mode="optimistic"/>
         <Security AppModuleJndiName="oracle.fodemo.storefront.store.service.StoreServiceAM"/>
         <Custom fod.application.issoaenabled="true"/>
      </AppModuleConfig>
      <AppModuleConfig 
               name="StoreFrontService"
               ApplicationName="oracle.fodemo.storefront.store.service.StoreServiceAM"
               jbo.project="StoreFrontService"
               DeployPlatform="SI">
         <AM-Pooling jbo.ampool.resetnontransactionalstate="true"/>
         <Database jbo.SQLBuilder="ORACLE" jbo.locking.mode="optimistic"
                   jbo.TypeMapEntries="Java"/>
         <Security AppModuleJndiName="oracle.fodemo.storefront.store.service.StoreServiceAM"/>
         <Custom JDBCDataSource="java:comp/env/jdbc/FODDS"/>
      </AppModuleConfig>
   </AppModuleConfigBag>
</BC4JConfig>

Note that attributes of the AppModuleConfig tag appear with names matching their ADF Business Components properties (for example, the attribute jbo.locking.mode corresponds to the property jbo.locking.mode). It's also important to understand that if a property is currently set to its runtime default value in the Edit Business Components Configuration dialog, then JDeveloper does not write the entry to the bc4j.xcfg file.

41.2.3 How to Set Configuration Properties as System Parameters

As an alternative to specifying configuration properties in the bc4j.xcfg file, you can also set Java VM system parameters with the same property names. These system parameters will be used only if a corresponding property does not exist in the relevant bc4j.xcfg file for the application module in question. In other words, configuration parameters that appear in the application module configuration take precedence over parameters of the same name supplied as Java system parameters.

You typically set Java system parameters using the -D command line flag to the Java VM like this:

java -Dproperty=value -jar yourserver.jar

Alternatively, your Java EE container probably has a section in its own configuration files where Java system parameters can be specified for use at Java EE container startup time.

If you adopt the technique of specifying site-specific default values for Oracle ADF configuration parameters as Java system parameters, you should make sure that your application's bc4j.xcfg files do not include references to these parameters unless you want to define an application-module-specific exception to these global default values.

Caution:

The values of Idle Instance Timeout, Pool Polling Interval settings for both the Application Pool and the database Connection Pool are displayed and edited in this dialog as a number of seconds, but are saved to the configuration file in milliseconds. If you provide a value for any of these four parameters as a Java System parameter — or if you hand-edit the bc4j.xcfg file — make sure to provide these time interval values in milliseconds!

41.2.4 How to Programmatically Set Configuration Properties

You can set configuration properties programmatically by creating a Java class that implements the EnvInfoProvider interface in the oracle.jbo.common.ampool package. In your class, you override the getInfo() method and call put() to put values into the environment Hashtable passed in as shown in Example 41-2.

Example 41-2 Setting Environment Properties with a Custom EnvInfoProvider

package devguide.advanced.customenv.view;
import java.util.Hashtable;
import oracle.jbo.common.ampool.EnvInfoProvider;
/**
 * Custom EnvInfoProvider implementation to set
 * environment properties programmatically
 */
public class CustomEnvInfoProvider implements EnvInfoProvider {
  /**
   * Overridden framework method to set custom values in the
   * environment hashtable.
   * 
   * @param string - ignore
   * @param environment Hashtable of config parameters
   * @return null - not used
   */
  public Object getInfo(String string, Object environment) {
    Hashtable envHashtable = (Hashtable)environment;
    envHashtable.put("some.property.name","some value");
    return null;
  }
  /* Required to implement EnvInfoProvider */
  public void modifyInitialContext(Object object) {}
  /* Required to implement EnvInfoProvider */
  public int getNumOfRetries() {return 0;}
}

When creating an application module for a stateless or command-line-client, with the createRootApplicationModule() method of the Configuration class, you can pass the custom EnvInfoProvider as the optional second argument. In order to use a custom EnvInfoProvider in an ADF web-based application, you need to implement a custom session cookie factory class as shown in Example 41-3. To use your custom session cookie factory, set the jbo.ampool.sessioncookiefactoryclass configuration property to the fully-qualified name of your custom session cookie factory class.

Example 41-3 Custom SessionCookieFactory to Install a Custom EnvInfoProvider

package devguide.advanced.customenv.view;
import java.util.Properties;
import oracle.jbo.common.ampool.ApplicationPool;
import oracle.jbo.common.ampool.EnvInfoProvider;
import oracle.jbo.common.ampool.SessionCookie;
import oracle.jbo.http.HttpSessionCookieFactory;
/**
 * Example of custom http session cookie factory
 * to install a custom EnvInfoProvider implementation
 * for an ADF web-based application.
 */
public class CustomHttpSessionCookieFactory
       extends HttpSessionCookieFactory {
  public SessionCookie createSessionCookie(String appId,
                                           String sessionId, 
                                           ApplicationPool pool,
                                           Properties props) {
    SessionCookie cookie =
      super.createSessionCookie(appId, sessionId,pool, props);
    EnvInfoProvider envInfoProv = new CustomEnvInfoProvider();
    cookie.setEnvInfoProvider(envInfoProv);
    return cookie;
  }
}

41.2.5 What You May Need to Know About Configuration Property Scopes

Each runtime configuration property used by ADF Business Components has a scope. The scope of each property indicates at what level the property's value is evaluated and whether its value is effectively shared (i.e. static) in a single Java VM, or not. The ADF Business Components PropertyManager class is the registry of all supported properties. It defines the property names, their default values, and their scope. This class contains a main() method so that you can run the class from the command line to see a list of all the configuration property information.

Assuming JDEVHOME is the JDeveloper installation directory, to see this list of settings for reference, do the following:

$ java -cp JDEVHOME/BC4J/lib/bc4jmt.jar oracle.jbo.common.PropertyManager

Issuing this command will send all of the ADF Business Components configuration properties to the console. It also lists a handy reference about the different levels at which you can set configuration property values and remind you of the precedence order these levels have:

---------------------------------------------------------------
Properties loaded from following sources, in order:
1. Client environment [Provided programmatically
                       or declaratively in bc4j.xcfg]
2. Applet tags
3. -D flags (appear in System.properties)
4. bc4j.properties file (in current directory)
5. /oracle/jbo/BC4J.properties resource
6. /oracle/jbo/commom.jboserver.properties resource
7. /oracle/jbo/common.Diagnostic.properties resource
8. System defined default
---------------------------------------------------------------

You'll see each property is listed with one of the following scopes:

  • MetaObjectManager

    Properties at this scope are initialized once per Java VM when the ADF PropertyManager is first initialized.

  • SessionImpl

    Properties at this scope are initialized once per invocation of ApplicationModule.prepareSession().

  • Configuration

    Properties at this scope are initialized when the ApplicationModule pool is first created and the application module's configuration is read the first time.

  • Diagnostic

    Properties at this scope are specific to the built-in ADF Business Components diagnostic facility.

At each of these scopes, the layered value resolution described above is performed when the properties are initialized. Whenever property values are initialized, if you have specified them in the Client Environment (level 1 in the resolution order) the values will take precedence over values specified as System parameters (level 3 in the resolution order).

The Client Environment is a hashtable of name/value pairs that you can either programatically populate, or which will be automatically populated for you by the Configuration object when loaded, with the name/value pairs it contains in its entry in the bc4j.xcfg file. The implication of this is that for any properties scoped at MetaObjectManager level, the most reliable way to ensure that all of your application modules use the same default value for those properties is to do both of the following:

  1. Make sure the property value does not appear in any of your application module's bc4j.xcfg file configuration name/value pair entries.

  2. Set the property value using a Java system property in your runtime environment.

If, instead, you leave any MetaObjectManager-scoped properties in your bc4j.xcfg files, you will have the undesirable behavior that they will take on the value specified in the configuration of the first application module whose pool gets created after the Java VM starts up.

41.2.6 What You May Need to Know About How Database and Application Module Pools Cooperate

How ADF application module pools use the database connection pool depends on the setting of the jbo.doconnectionpooling application module configuration parameter. In the Configuration Manager panel shown in Figure 41-1, you set this parameter using the checkbox labelled Disconnect Application Module Upon Release.

Note:

The notion of disconnecting the application module upon release to the pool better captures what the actual feature is doing than the related configuration parameter name (jbo.doconnectionpooling) does. The setting of jbo.doconnectionpooling=false does not mean that there is no database connection pooling happening. What it means is that the application module is not disconnected from its JDBC connection upon check in back to the application module pool.

If the default setting of jbo.doconnectionpooling=false is used, then when an application module instance is created in any pool it acquires a JDBC connection from the appropriate connection pool (based on the JDBC URL in the ADF case, or from the underlying JDBC data source implementation's pool in the case of a JNDI data source name). That application module instance holds onto the JDBC connection object that it acquired from the pool until the application module instance is removed from the application module pool. During its lifetime, that application module instance may service many different users, and ADF worries about issuing rollbacks on the database connection so that different users don't end up getting pending database state confused. By holding onto the JDBC connection, it allows each application module instance to keep its JDBC PreparedStatement objects open and usable across subsequent accesses by clients, thereby providing the best performance.

If jbo.doconnectionpooling=true, then each time a user session finishes using an application module (typically at the end of each HTTP request), the application module instance disassociates itself with the JDBC connection it was using on that request and it returns it to the JDBC connection pool. The next time that application module instance is used by a user session, it will reacquire a JDBC connection from the JDBC connection pool and use it for the span of time that application module is checked out of the application module pool (again, typically the span of one HTTP request). Since the application module instance "unplugs" itself from the JDBC connection object used to create the PreparedStatements it might have used during the servicing of the current HTTP request, those PreparedStatements are no longer usable on the next HTTP request because they are only valid in the context of the Connection object in which they were created. So, when using the connection pooling mode turned on like this, the trade-off is slightly more JDBC overhead setup each time, in return for using a smaller number of overall database connections.

The key difference is seen when many application module pools are all using the same underlying database user for their application connection.

  • If 50 different application module pools each have even just a single application module instance in them, with jbo.doconnectionpooling=false there will be 50 JDBC application connections in use. If the application module pooling parameters are set such that the application module pools are allowed to shrink to 0 instances after an appropriate instance idle timeout by setting jbo.ampool.minavailablesize=0, then when the application module is removed from its pool, it will put back the connection its holding onto.

  • In contrast, if 50 different application module pools each have a single application module instance and jbo.doconnectionpooling=true, then the amount of JDBC connections in use will depend on how many of those application modules are simultaneously being used by different clients. If an application module instance is in the pool and is not currently being used by a user session, then with jbo.doconnectionpooling=true it will have released its JDBC connection back to the connection pool and while the application module instance is sitting there waiting for either another user to need it again, or to eventually be cleaned up by the application module pool monitor, it will not be "hanging on" to a JDBC connection.

Performance Tip:

Leave the jbo.doconnectionpooling configuration parameter set to false for best performance without sacrificing scalability and reliability. Database connection pooling is still achieved through application module pooling. The only exception is when multiple application module pools (and therefore a large number of application module instances) share the same database, making the total available database connections the highest priority.

Highest performance is achieved by not disconnecting the application module instance from its database connection on each check in to the application module pool. Accordingly, the default setting of the jbo.doconnectionpooling configuration parameter is false. The pooling of application module instances is already an effective way to optimize resource usage, and the Oracle ADF runtime is more efficient when you do not have to disconnect application module instances from their associated JDBC connection after each release to the pool. Effectively, by pooling the application modules which are related one-to-one with a JDBC connection, you are already achieving a pooling of database connections that is optimal for most Fusion web applications.

However, when minimizing the total overall number of database sessions is a priority, one situation in which it might be appropriate to use database connection pooling is when you have a large number of application module pools all needing to use database connections from the same underlying application user at the database level. In this case, the many application module pools can economize on the total overall database sessions by sharing a single, underlying database connection pool of JDBC connections, albeit at a loss of efficiency of each one. This choice would be favored only if total overall database sessions is of maximum priority. In this scenario, if a user scrolls through some, but not all rows of a view object's row set, then with jbo.doconnectionpooling=true, Oracle ADF will automatically passivate the pending application module state (including current row information) so that the next time the application module is used, the queried view object can be put back into the same current row with the same initial rows fetched. This passivation behavior may reduce performance.

41.2.7 What You May Need to Know About Application Module Pool Parameters

The application module pool configuration parameters fall into three logical categories relating to pool behavior, pool sizing, and pool cleanup behavior.

41.2.7.1 Pool Behavior Parameters

Table 41-1 lists the application module configuration parameters that affect the behavior of the application module pool.

Table 41-1 Application Module Pool Behavior Configuration Parameters

Pool Configuration Parameter Description

Failover Transaction State Upon Managed Release

(jbo.dofailover)

Enables eager passivation of pending transaction state each time an application module is released to the pool in "Managed State" mode. See Section 40.2.2.2, "How Passivation Changes When Optional Failover Mode is Enabled" for more information.

Fusion web applications should set enable failover (true) to allow any other application module to activate the state at any time.

This feature is disabled by default (false)

Row-Level Locking Behavior Upon Release

(jbo.locking.mode)

Forces the application module pool not to create a pending transaction state on the database with row-level locks each time the application module is released to the pool. See Section 40.11.1, "How to Set Applications to Use Optimistic Locking" for more information.

Fusion web applications should set the locking mode to optimistic to avoid creating the row-level locks.

This feature is disabled by default (pessimistic).

Disconnect Application Module Upon Release

(jbo.doconnectionpooling)

Forces the application module pool to release the JDBC connection used each time the application module is released to the pool. See Section 41.2.6, "What You May Need to Know About How Database and Application Module Pools Cooperate" for more information.

This feature is disabled by default (false).

Enable Application Module Pooling

(jbo.ampool.doampooling)

Enables application module pooling by default. Whenever you deploy your application in a production environment the default setting of jbo.ampool.doampooling to true and is the way you will run your application. But, as long as you run your application in a test environment, setting the property to false can play an important role in your testing. When this property is false, there is effectively no application pool. See Section 40.10, "Testing to Ensure Your Application Module is Activation-Safe" for more information.

This feature is disabled by default (false)

Support Dynamic JDBC Credentials

(jbo.ampool.dynamicjdbccredentials)

Enables additional pooling lifecycle events to allow developer-written code to change the database credentials (username/password) each time a new user session begins to use the application module.

This feature is enabled by default (true), however this setting is a necessary but not sufficient condition to implement the feature. The complete implementation requires additional developer-written code.

Reset Non-Transactional State Upon Unmanaged Release

(jbo.ampool.resetnontransactionalstate))

Forces the application module to reset any non-transactional state like view object runtime settings, JDBC prepared statements, bind variable values, etc. when the application module is released to the pool in unmanaged or "stateless" mode.

This feature is enabled by default (true). Disabling this feature can improve performance, however since it does not clear bind variable values, your application needs to ensure that it systemically sets bind variable values correctly. Failure to do so with this feature disabled can mean one user might see data with another users bind variable values.)


41.2.7.2 Pool Sizing Parameters

Table 41-2 lists the application module configuration parameters that affect the sizing of the application module pool.

Table 41-2 Application Module Pool Sizing Configuration Parameters

Pool Configuration Parameter Description

Initial Pool Size

(jbo.ampool.initpoolsize)

The number of application module instances to created when the pool is initialized.

The default is 0 (zero) instances. A general guideline is to configure this to 10% more than the anticipated number of concurrent application module instances required to service all users.

Creating application module instances during initialization takes the CPU processing costs of creating application module instances during the initialization instead of on-demand when additional application module instances are required.

Maximum Pool Size

(jbo.ampool.maxpoolsize)

The maximum number of application module instances that the pool can allocate. The pool will never create more application module instances than this limit imposes.

The default is 5000 instances. A general guideline is to configure this to 20% more than the initial pool size to allow for some additional growth. If this is set too low, then some users may see an error accessing the application if no application module instances are available.

Referenced Pool Size

(jbo.recyclethreshold)

The maximum number of application module instances in the pool that attempt to preserve session affinity for the next request made by the session which used them last before releasing them to the pool in managed-state mode.

The referenced pool size should always be less than or equal to the maximum pool size. The default is to allow 10 available instances to try and remain "loyal" to the affinity they have with the most recent session that released them in managed state mode.

Configure this value to maintain the application module instance's affinity to a user's session. A general guideline is to configure this to the expected number of concurrent users that perform multiple operations with short think times. If there are no users expected to use the application with short think times, then this can be configured to 0 zero to eliminate affinity.

Maintaining this affinity as much as possible will save the CPU processing cost of needing to switch an application module instance from one user session to another.

Maximum Instance Time to Live

(jbo.ampool.timetolive)

The number of milliseconds after which to consider an application module instance in the pool as a candidate for removal during the next resource cleanup regardless of whether it would bring the number of instances in the pool below minavailablesize.

The default is 3600000 milliseconds of total time to live (which is 3600 seconds, or one hour). The default value is sufficient for most applications.


41.2.7.3 Pool Cleanup Parameters

A single "application module pool monitor" per Java VM runs in a background thread and wakes up every so often to do resource reclamation. Table 41-3 lists the parameters that affect how resources are reclaimed when the pool monitor does one of its resource cleanup passes.

Best Practice:

When you specify the length of time between application module pool cleanup passes, set all application modules to use the same Pool Polling Interval value. Since there is only a single application monitor pool monitor per Java VM, the value that will effectively be used for the application module pool monitor polling interval will be the value found in the application module configuration read by the first application module pool that gets created. Setting all application modules to use the same value ensures that this value is set in a predictable way.

Table 41-3 Application Module Resource Management Configuration Parameters

Pool Configuration Parameter Description

Pool Polling Interval

(jbo.ampool.monitorsleepinterval)

The length of time in milliseconds between pool resource cleanup.

While the number of application module instances in the pool will never exceed the maximum pool size, available instances which are candidates for getting removed from the pool do not get "cleaned up" until the next time the application module pool monitor wakes up to do its job.

The default is to have the application module pool monitor wake up every 600000 milliseconds (which is 600 seconds, or ten minutes). Configuring a lower interval results in inactive application module instances being removed more frequently to save memory. Configuring a higher interval results in less frequent resource cleanups.

Maximum Available Size

(jbo.ampool.maxavailablesize)

The ideal maximum number of available application module instances in the pool when not under abnormal load.

When the pool monitor wakes up to do resource cleanup, it will try to remove available application module instances to bring the total number of available instances down to this ideal maximum. Instances that have been not been used for a period longer than the idle instance time-out will always get cleaned up at this time, then additional available instances will be removed if necessary to bring the number of available instances down to this size.

The default maximum available size is 25 instances. Configure this to leave the maximum number of available instances desired after a resource cleanup. A lower value generally results in more application module instances being removed from the pool on a cleanup.

Minimum Available Size

(jbo.ampool.minavailablesize)

The minimum number of available application module instances that the pool monitor should leave in the pool during a resource cleanup operation.

Set to 0 (zero) if you want the pool to shrink to contain no instances when all instances have been idle for longer than the idle time-out after a resource cleanup.

The default is 5 instances.

Idle Instance Timeout

(jbo.ampool.maxinactiveage)

The number of milliseconds after which to consider an inactive application module instance in the pool as a candidate for removal during the next resource cleanup.

The default is 600000 milliseconds of idle time (which is 600 seconds, or ten minutes). A lower value results in more application module instances being marked as a candidate for removal at the next resource cleanup. A higher value results in fewer application module instances being marked as a candidate for removal at the next resource cleanup.

Maximum Instance Time to Live

(jbo.ampool.timetolive)

The number of milliseconds after which to consider an connection instance in the pool as a candidate for removal during the next resource cleanup regardless of whether it would bring the number of instances in the pool below minavailablesize.

The default is 3600000 milliseconds of total time to live (which is 3600 seconds, or one hour). A lower value reduces the time an application module instance can exist before it must be removed at the next resource cleanup. The default value is sufficient for most applications. A higher value increases the time an application module instance can exist before it must be removed at the next cleanup.


41.2.8 What You May Need to Know About Data Source Configuration

When you specify a JDBC data source as your application module's connection type, any configuration parameters that you have configured for the database connection pool will be ignored. To configure the connection pool for your data source, you must use the means provided by your Java EE container. In the case of Oracle WebLogic Server, you configure the data source using the Oracle WebLogic Server Administration Console.

The main steps for configuring JDBC data sources are:

  1. Create a data source for each data base that you want to connect to. When you create the data source, specify the configuration options to match the ones for ADF Business Components database connection pools described in Table 41-4. The configuration settings that you specify will depend on your database and the capacity planning that you need anticipate for your application.

    For details about configuring JDBC data sources and connection pool capacity planning, see Oracle Fusion Middleware Configuring and Managing JDBC for Oracle WebLogic Server.

  2. Optionally, configure transaction options for the data source.

  3. Optionally, configure connection testing options for the data source.

  4. Optionally, target the data source to additional servers and clusters.

For detailed procedures for each of these steps, see the topic "Configure JDBC data sources" in the Administration Console Online Help.

Table 41-4 Equivalent Oracle WebLogic Server Data Source Parameters

ADF Business Components Parameter \Oracle WebLogic Server Parameter

Initial Pool Size

(jbo.initpoolsize)

Initial Capacity

Maximum Pool Size

(jbo.maxpoolsize)

Maximum Capacity

Pool Polling Interval

(jbo.poolmonitorsleepinterval)

No equivalent for Oracle WebLogic Server.

Maximum Available Size

(jbo.poolmaxavailablesize)

Maximum Capacity

Minimum Available Size

(jbo.poolminavailablesize)

Maximum Capacity

Idle Instance Timeout

(jbo.poolmaxinactiveage)

Shrink Frequency Seconds


41.2.9 What You May Need to Know About Database Connection Pool Parameters

If you are using a JDBC URL for your connection information so that the ADF database connection pool is used, then configuration parameters listed in Table 41-5 can be used to tune the behavior of the database connection pool. A single "database connection pool monitor" per Java VM runs in a background thread and wakes up every so often to do resource reclamation. The parameters in Table 41-3 include the ones that affect how resources are reclaimed when the pool monitor does one of its resource cleanup passes.

Note:

The configuration parameters for database connection pooling have MetaObjectManager scope (described in Section 41.2.5, "What You May Need to Know About Configuration Property Scopes" earlier). This means their settings are global and will be set once when the first application module pool in your application is created. To insure the most predictable behavior, leave the values of these parameters in the Connection Pool section of the Pooling and Scalability tab at their default values — so that no entry for them is written into the bc4j.xcfg file — and to instead set the desired values for the database connection pooling tuning parameters as Java System Parameters in your Java EE container.

Table 41-5 Database Connection Pool Parameters

Pool Configuration Parameter Description

Initial Pool Size

(jbo.initpoolsize)

The number of JDBC connection instances to created when the pool is initialized

The default is an initial size of 0 instances.

Maximum Pool Size

(jbo.maxpoolsize)

The maximum number of JDBC connection instances that the pool can allocate.

The pool will never create more JDBC connections than this imposes. The default is 5000 instances.

Pool Polling Interval

(jbo.poolmonitorsleepinterval)

The length of time in milliseconds between pool resource cleanup.

While the number of JDBC connection instances in the pool will never exceed the maximum pool size, available instances which are candidates for getting removed from the pool do not get "cleaned up" until the next time the JDBC connection pool monitor wakes up to do its job.

The default is 600000 milliseconds of idle time (which is 600 seconds, or ten minutes). Configuring a lower interval results in inactive connection instances being removed more frequently to save memory. Configuring a higher interval results in less frequent resource cleanups.

Maximum Available Size

(jbo.poolmaxavailablesize)

The ideal maximum number of JDBC connection instances in the pool when not under abnormal load.

When the pool monitor wakes up to do resource cleanup, it will try to remove available JDBC connection instances to bring the total number of available instances down to this ideal maximum. Instances that have been not been used for a period longer than the idle instance time-out will always get cleaned up at this time, then additional available instances will be removed if necessary to bring the number of available instances down to this size. The default is an ideal maximum of 25 instances (when not under load).

Minimum Available Size

(jbo.poolminavailablesize)

The minimum number of available JDBC connection instances that the pool monitor should leave in the pool during a resource cleanup operation. Set to zero (0) if you want the pool to shrink to contain no instances when all instances have been idle for longer than the idle time-out.

The default is to not let the minimum available size drop below 5 instances.

Idle Instance Timeout

(jbo.poolmaxinactiveage)

The number of seconds after which to consider an inactive JDBC connection instance in the pool as a candidate for removal during the next resource cleanup.

The default is 600000 milliseconds of idle time (which is 600 seconds, or ten minutes).


Notice that since the database connection pool does not implement the heuristic of session affinity, there is no configuration parameter for the database connection pool which controls the referenced pool size.

41.3 Initializing Database State and Pooling Considerations

Sometimes you may need to invoke stored procedures to initialize database state related to the current user's session. The correct place to perform this initialization is in an overridden prepareSession() method of your application module.

41.3.1 How to Set Database State Per User

The Fusion web application can set database state on a per-user basis. You typically create a database CONTEXT namespace, associate a PL/SQL procedure with it, and then use the SYS_CONTEXT() SQL function to reference values from the context.

For example, you can use the PL/SQL package to set and get a package-level variable that holds the name of the currently authenticated Fusion web application user as shown in Example 41-4.

Example 41-4 CONTEXT_PKG PL/SQL Package

create or replace package context_pkg as
  procedure set_app_user_name(username varchar2);
  function app_user_name return varchar2;
end context_pkg;

Then your application can define the WHERE clause of a view object to reference the context_pkg.app_user_name function and query the per-user state.

To set the database state, the application module framework extension class (AppModuleImpl.java) defines a callStoredProcedure() helper method similar to the ones in Section 37.5.2, "How to Invoke Stored Procedure with Only IN Arguments." The custom application module class then extends this framework extension class and defines the setCurrentUserInPLSQLPackage() helper method shown in Example 41-5. The helper method uses the callStoredProcedure() method to invoke the context_pkg.set_app_user_name() stored procedure, passing the value of the currently authenticated user as a parameter value.

Example 41-5 Method to Call Context_Pkg.Set_App_User_Name Stored Procedure

// In CustomAppModuleImpl.java
public void setCurrentUserInPLSQLPackage() {
  String user = getUserPrincipalName();
  callStoredProcedure("context_pkg.set_app_user_name(?)",new Object[]{user});
}

With this helper method in place, the custom application module class then overrides the prepareSession() method as shown in Example 41-6.

Example 41-6 Overridden afterConnect() and prepareSession() to Set Database State

// In CustomAppModuleImpl.java
  protected void prepareSession(Session session) {
    super.prepareSession(session);
    getLoggedInUser().retrieveUserInfoForAuthenticatedUser();     
    setUserIdIntoUserDataHashtable();
    setCurrentUserInPLSQLPackage();      
  }

41.3.2 What You May Need to Know About Database User State and jbo.doconnectionpooling = true

The default setting for jbo.doconnectionpooling is false. This means the application module instance hangs onto its JDBC connection while it's in the application module pool. This is the most efficient setting because the application module can keep its JDBC prepared statements open across application module checkouts/checkins.The application module instance will trigger its prepareSession() method each time a new user session begins using it.

If you set jbo.doconnectionpooling to true, then on each checkout of an application module from the pool, that application module pool will acquire a JDBC connection from the database connection pool and use it during the span of the current request. At the end of the request when the application module is released back to the application module pool, that application module pool releases the JDBC connection it was using back to the database connection pool.

It follows that with jbo.doconnectionpooling set to true the application module instance in the pool may have a completely different JDBC connection each time you check it out of the pool. In this situation, the prepareSession() method will fire each time the application module is checked out of the pool to give you a chance to reinitialize the database state.