Skip Headers
Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers
10g Release 3 (10.1.3.0)
B25947-01
  Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

28.2 The ADF Business Components State Management Facility

The application module component and application module pool cooperate to offer a generic solution to database-backed, application state management. This feature enables you to easily create web applications that support multi-step use cases without falling prey to the memory, reliability, or implementation complexity problems described in the previous section.

Your ADF Business Components-based application automatically manages the application state of each user session. This provides the simplicity of a stateful programming model that you are used to in previous 4GL tools, yet, implemented in a way that delivers scalability nearing that of a purely stateless application. Understanding what happens behind the scenes is essential to make the most efficient use of this important feature.

28.2.1 Basic Architecture of the State Management Facility

You can use application module components to implement completely stateless applications or to support a unit of work that spans multiple browser pages. Figure 28-4 illustrates the basic architecture of the state management facility to support these multi-step scenarios. An application module supports passivating its pending transaction state to an XML document, which is stored in the database in a single, generic table, keyed by a unique passivation snapshot ID. It also supports the reverse operation of activating pending transaction state from one of these saved XML "snapshots." This passivation and activation is performed automatically by the application module pool when needed.

Figure 28-4 ADF Provides Generic, Database-Backed State Management

Image describes ADF state management

The ADF binding context is the one object that lives in the HttpSession for each end user. It hold references to lightweight application module data control objects that manage acquiring an application module instance from the pool at the beginning of each request and releasing it to the pool at the end of each request. The data control holds a reference to the ADF "session cookie" that identifies the user session. In particular, business domain objects created or modified in the pending transaction are not saved in the HttpSession using this approach. This minimizes both the session memory required per user and eliminates the network traffic related to session replication if the servers are configured in a cluster.

For improved reliability, if you have multiple application servers and you enable the optional ADF Business Components failover support, then subsequent end-user requests can be handled by any server in your server farm or cluster. The ADF session cookie saved in the client browser is enough to "reactivate" the pending application state from the database-backed XML snapshot if required, regardless of what server handles the request.

28.2.2 Understanding When Passivation and Activation Occurs

To better understand when the automatic passivation and activation of application module state occurs, consider the following simple case:

  1. At the beginning of an HTTP request, the application module data control handles the beginRequest event by checking out an application module instance from the pool.

    The application module pool returns an unreferenced instance. An unreferenced application module is one that is not currently managing the pending state for any other user session.

  2. At the end of the request, the application module data control handles the endRequest event by checking the application module instance back into the pool in "managed state" mode.

    That application module instance is now referenced by the data control that just used it. And the application module instance is an object that still contains pending transaction state made by the data control (that is, entity object and view object caches; updates made but not committed; and cursor states), stored in memory. As you'll see below, it's not dedicated to this data control, just referenced by it.

  3. On a subsequent request, the same data control — identified by its SessionCookie — checks out an application module instance again.

    Due to the "stateless with user affinity" algorithm the pool uses, you might assume that the pool returns the exact same application module instance, with the state still there in memory.

Sometimes due to a high number of users simultaneously accessing the site, application module instances must be sequentially reused by different user sessions. In this case, the application pool must recycle a currently referenced application module instance for use by another session, as follows:

  1. The application module data control for User A's session checks an application module instance into the application pool at the end of a request. Assume this instance is named AM1.

  2. The application module data control for User Z's new session requests an application module instance from the pool for the first time, but there are no unreferenced instances available. The application module pool then:

    • Passivates the state of instance AM1 to the database.

    • Resets the state of AM1 in preparation to be used by another session.

    • Returns the AM1 instance to User Z's data control.

  3. On a subsequent request, the application module data control for User A's session requests an application module instance from the pool. The application module pool then:

    • Obtains an unreference instance.

      This could be instance AM1, obtained by following the same steps as in (2) above, or another AM2 instance if it had become unreferenced in the meantime.

    • Activates the appropriate pending state for User A from the database.

    • Returns the application module instance to User A's data control.

The process of passivation, activation, and recycling allows the state referenced by the data control to be preserved across requests without requiring a dedicated application module instance for each data control. Both browser users in the above scenario are carrying on an application transaction that spans multiple HTTP requests, but the end users are unaware whether the passivation and activation is occurring in the background. They just continue to see the pending changes. In the process, the pending changes never need to be saved into the underlying application database tables until the end user is ready to commit the logical unit of work.

The application module pool makes a best effort to keep an application module instance "sticky" to the current data control whose pending state it is managing. This is known as maintaining user session affinity. The best performance is achieved if a data control continues to use exactly the same application module instance on each request, since this avoids any overhead involved in reactivating the pending state from a persisted snapshot.

28.2.3 How Passivation Changes When Optional Failover Mode is Enabled

There is a parameter called jbo.dofailover that can be set in your application module configuration on the Pooling and Scalability tab of the Configuration Editor. This parameter controls when and how often passivation occurs. When the failover feature is disabled, which it is by default, then application module pending state will only be passivated on demand when it must be. This occurs just before the pool determines it must hand out a currently-referenced application module instance to a different data control.

In contrast, with the failover feature turned on, the application module's pending state is passivated every time it is checked back into application module pool. This provides the most pessimistic protection against application server failure. The application module instances' state is always saved and may be activated by any application module instance at any time. Of course, this capability comes at expense of the additional overhead of eager passivation on each request.


Note:

When running or debugging an application that uses failover support within the JDeveloper environment, you are frequently starting and stopping the embedded OC4J server. The ADF failover mechanism has no way of knowing whether you stopped the embedded server to simulate an application server failure, or whether you stopped it because you want to retest something from scratch in a "fresh" server instance. If you intend doing the latter, Oracle recommends exiting out of your browser before restarting the application on the embedded server. This eliminates the chance that you will be confused by the correct functioning of the failover mechanism when you didn't intend to be testing that aspect of your application.