Clarification of Oracle ADF State Management
By Ammar Sajdi
May 15, 2011
For the sake of this discussion, it will assumed that there are only two users accessing the application and only one application module available in the application module poolThe following is an attempt to clarify how exactly ADF manages application module pool.
- Application Module in unreferenced State
- No Reference to any Client page in the Http Session
First User Sends a Request
- At the beginning of the Request, a session references a Data Control object which in turns looks for an Application Module (AM) in the pool. It finds an unreferenced AM and grabs it for its use AM1 ;( An unreferenced AM is one that does not hold active content for any user session). During the request, the status of the AM is changed to BUSY and the AM instance contains User1 transaction information together with Current row information etc ..
- At the End of the Request, AM1 is checked back to the Pool with AM states changed to Referenced (Or Managed). Note that the AM is back in the pool without constraints and is not tied to any specified session.
- User Sends another Request, Second user is still Idle
- The Data Control (which resides in the same user session) will again look for AM in the pool and since the pool uses session affinity algorithm, an attempt is made to return the same previous AM instance. The attempt will be successful, because no other session is competing for the AM in the pool. AM1 will be returned. Its status will again become Busy
- At the end of the request, AM1 is returned back to the pool in Managed state.
- Second User Sends a Request
- At the beginning of the Request, the second user Data Control will try to grab AM1. AM1 is however in a managed state and is referenced by the first Session. Any attempt to over write the contents of AM1 shall jeopardize the first user transaction. Therefore, the AM pool management needs to make AM1 available to user2, but only after it recycles the contents of AM1. A process called passivation starts, in which AM1 contents are persisted into the Database or to an OS file. This is called a snapshot. After passivation is completed, AM1 is now in an UNREFERENCED State and at this moment, Session2 Data Control grabs AM1, changes it status to BUSY and becomes the active AM for user2.
- At the end of the request, the Data control in the second user session releases the AM back to the Pool in MANAGED state
- First User Sends a Request
- When the first user sends another request, he/she should not be aware of the fact that AM1 now references a different user session. In order to make this completely transparent, the Pool Management will recycle AM1 again, after it persists AM1 state through passivation, it will carry out an activation process. This process reads User1 snapshot from the Persisted snapshot and back into AM1. AM1 now references User1 session and maintains its current transaction.
- 2 Finally, at the end of the request, the AM1 is released back to the application module waiting to serve another request. If the request is for the first user, the process continues without passivation/activation cycle. If on the other hand, the request is for the second user, user2 previous snapshot needs to be activated.
Activation / passivation cycle does not take place at every request. (one exception is when failover is enabled). Otherwise, it only occurs when user requests far exceed the no of available AM.
There are parameter that gives you control over the AM in the pool. Like Max, min etc …
Note that in the above scenario , it neither of the users issues a submit or a rollback, while at the same time the contents of the transactions are maintained across several requests.
It is important to understand that whenever the session passivated, a JDBC database rollback is issued. This rollback is not related to the Application Module, your EO will remain intact. But you need to be careful about stored procedures that you executed with DML, or information posted to the database through POST_CHANGES operation.
When the session is passivated and then activated to another user, its JDBC connection remains with it. Therefore, any session information are lost. This is important when you design RLS, and that is why we need to set the context information at each PrepareSession event.