Showing posts with label BC Passivation. Show all posts
Showing posts with label BC Passivation. Show all posts

18 March 2011

Application Module Pooling and State Management

Last updated: 29/3/2011
How it works?

Application Pooling
Due to the natural "think time" inherent in the end user's interaction with your application user interface, the number of application module instances in the pool can be smaller than the overall number of active users using the system.  For this reason, ADF applications provide the application module pooling feature. This facility manages a configurable set of application module instances that grows and shrinks as the end-user load on your application changes during the day.
As shown below, as a given end user visits multiple pages in your application to accomplish a logical task, with each page request an application module instance in the pool is acquired automatically from the pool for the lifetime of that one request. At the end of the request, the instance is automatically returned to the pool for use by another user session. In order to protect the end user's work against application server failure, the application module supports the ability to freeze the set of pending changes in its entity caches to a persistent store by saving an XML snapshot describing the change set. For scalability reasons, this state snapshot is typically saved in a state management schema that is a different database schema than the one containing the application data.

State management
The PS_TXN and PS_TXN_SEQ are used by ADF to serialize user session state to the database (the state management schema).PS_TXN will only get created when/if an application module needs to be passivated. If your application module pool is big enough, it's possible that you won't see it get created.

More on BC Passivation in related posts.

Part of this post is from excellent Chris Muir post and Simon Lessard Forum comment. Thanx.

Sample/Test case
Find sample/test case in Andrejus excellent post Demystifying ADF BC Passivation and Activation!


Dig:

17 March 2011

jbo.dofailover=true, PS_TXN and Browser Cookie Limit

An interesting post by Steve Muench, regarding all the above. It's a bit old (November 2004) and something might change since then but nevertheless it worth reading. Reposting below:

This week one of our worldwide support engineers was working with a customer experiencing a problem of having their HTTP session sporadically get dropped in their ADF-based application. The problem only occurred when users would use the Internet Explorer browser; it didn't reproduce with Firefox, for example, however the customer's userbase are IE users, so switching to Firefox wasn't an option as a workaround.
The support engineer did some testing to discover that Internet Explorer strictly adheres to the RFC2109 specification's limit of 20 cookies per domain. I worked with him to build an example servlet which accessed the J2EE web container's servlet session, and then proceeded to add a cookie with a unique name on each time the page would get refreshed...Cookie1, Cookie2, Cookie3, etc. After refreshing the page 19 times using the Internet Explorer browser, we could see we had twenty cookies like this:
JSESSIONID=...
Cookie1=...
Cookie2=...
    :
  etc.
    :
Cookie19=...
Of course, the JSESSIONID is the cookie used by the web container to keep your browser session "connected" to the server-side servlet session object over the stateless HTTP protocol. If you lose the JSESSIONID cookie, then to the server, the next time you visit it's as if it was your first time again. Refreshing the page one more time with our test servlet, showed that Internet Explorer -- having hit its limit of 20 cookies -- picked the least recently set cookie and got rid of it to make room for the new Cookie20 we created. It turns out that the least recently set cookie was the very JSESSIONID cookie that was our lifeline to the servlet session. Ouch! With Firefox, it appeared that fifty cookies was the limit in our testing, while other browers like Opera had yet another limit like 30. But in IE, this effect occurred at the RFC2109 20 cookie limit.
The support engineer asked the customer whether the own application was creating lots of cookies, but the response was that they weren't creating any cookies themselves. Then he asked them how many distinct ADF application modules their JSP pages were using, and the answer was "about 25". Next he asked them if they were using the ADF Business Components failover mode. They didn't remember having set it, so they were using the default which is jbo.dofailover=true. That is, the failover mode is on by default unless you disabled it in your application module configuration or by supplying a Java System parameter named jbo.dofailover=false at system startup time.
So, the support engineer had found the problem. Each ADF data control that is based on an ADF application module and which is being used in failover mode, saves a browser cookie that contains the persistent snapshot ID of the pending application module transaction state (which by default is saved in the database in a BLOB in the PS_TXN table, with that persistent snapshot id as its primary key. If you use 25 unique application module-based data controls in your application and you leave the failover mode on, you'll need to save 25 browser-side cookies to provide that failover support. If the middle-tier application server you were using goes down, on your next request, whatever server you do end up getting serviced by uses the value of the persistent snapshot id in the browser failover cookie for each data control to rendezvous with the right persistently stored pending changes.
Trouble is, if you need 25 cookies plus the JSESSIONID which makes 26, then at some point you'll hit your 20-cookie limit in Internet Explorer, and there's a chance that IE will throw out your JSESSION cookie, which cuts off your browser user's lifeline to the session. That in an of itself wouldn't cause trouble for ADF, but in this customer's case, they had placed a user login object of their own creation in the session, so it was no longer there once Internet Explorer had forgotten its JSESSIONID cookie.
The solution? The customer didn't actually need the failover feature, so they added the -Djbo.dofailover=false Java VM parameter to their application server startup to disable the ADF failover mode, and the problem has gone away.
One tip to help make sure that your ADF Business Components runtime configuration settings are actually getting set to what you think they are, is to run with the ADF Business Components diagnostics turned on -- which you do by adding the Java VM parameter -Djbo.debugoutput=file -- and then grep through the diagnostics files that will be named bc4j*.log in the system temp directory for the ADF configuration property name. The diagnostic output will tell you the value that it is using for each configuration property, and it will tell you where it read that value from (your configuration "client environment", System Property, etc.).


Check you browser limitations with this tool.

BC State management (Activation/Passsivation) best practises

For introductory notes regarding Application Module Pooling and State Management check here.

Supplying another database connection/schema for "state management": 
 Since it is often not desirable the main schema user to have the roles mentioned before (should not have the specific priveledges), Oracle recommends always supplying another database connection/schema for "state management". This means that we should have another database connection/schema to save PS_TXN table and PS_TXN_SEQ sequence. Define this user with jbo.server.internal_connection property in app module. Valid values for the jbo.server.internal_connection property in your configuration are:
  • A fully-qualified JDBC connection URL like:
    jdbc:oracle:thin:username/password@host:port:SID
  • A JDBC datasource name like:
    java:/comp/env/jdbc/YourJavaEEDataSourceName


Cleaning Up Temporary Storage Tables
JDeveloper supplies the bc4jcleanup.sql script in the /BC4J/bin directory to help with periodically cleaning up the application module state management table. Persistent snapshot records can accumulate over time if the server has been shutdown in an abnormal way, such as might occur during development or due to a server failure. Running the script in SQL*Plus will create the BC4J_CLEANUP PL/SQL package. The two relevant procedures in this package are:
  • PROCEDURE Session_State(olderThan DATE)     This procedure cleans-up application module session state storage for sessions older than a given date.
  • PROCEDURE Session_State(olderThan_minutes INTEGER)      This procedures cleans-up application module session state storage for sessions older than a given number of minutes.
You can schedule periodic cleanup of your ADF temporary persistence storage by submitting an invocation of the appropriate procedure in this package as a database job.

You can use an anonymous PL/SQL block like the one shown in Example 40-5 to schedule the execution of bc4j_cleanup.session_state() to run starting tomorrow at 2:00am and each day thereafter to cleanup sessions whose state is over 1 day (1440 minutes) old.
Example:  Scheduling Periodic Cleanup of the State Management Table




Dig more:

14 March 2011

TROUBLESHOOTING: Could not find saved view state for token ...

Chris Muir has an excellent post which resolves this kind of error. Reposting some of his material here:

Reason
The PS_TXN table  and PS_TXN_SEQ sequence are used by ADF to serialize user session state to the database. Without these database objects your application can't scale effectively to multiple users, you'll see some bizarre and wonderful behaviour as ADF chokes on not having the ability to serialize to the database objects. However it's not an ADF problem, the manuals clearly state that you need to grant specific privileges to the database user or create the database objects beforehand.

Resolution
Make sure that your database user has all 3 priviledges
  • CREATE TABLE,  
  • CREATE INDEX and  
  • CREATE SEQUENCE

Supplying another database connection/schema  for "state management"
Check BC State management (Activation/Passsivation) best practise
Some log entries to help identify it.

Under JDev 11g build 5188 you'll see the following WLS log entries:
First it'll throw errors that it can't retrieve user session state:
SEVERE: Could not find saved view state for token -505abe38
11/08/2009 14:29:29 org.apache.myfaces.trinidadinternal.application.StateManagerImpl restoreView
SEVERE: Could not find saved view state for token -505abe38
11/08/2009 14:29:29 org.apache.myfaces.trinidadinternal.application.StateManagerImpl restoreView
SEVERE: Could not find saved view state for token -505abe38
11/08/2009 14:29:29 org.apache.myfaces.trinidadinternal.application.StateManagerImpl restoreView
At a later point in the logs you'll see exceptions thrown, but they're not very meaningful:
WARNING: ADFc: Error while opening JDBC connection.
oracle.jbo.DMLException: JBO-26061: Error while opening JDBC connection.
 at oracle.jbo.server.ConnectionPool.createConnection(ConnectionPool.java:253)
 at oracle.jbo.server.ConnectionPool.instantiateResource(ConnectionPool.java:168)
 at oracle.jbo.pool.ResourcePool.createResource(ResourcePool.java:546)
 at oracle.jbo.pool.ResourcePool.useResource(ResourcePool.java:327)
Further in the logs you may see the following TNS Listener issue (though this may just be particular to my Oracle XE setup):
Caused by: java.sql.SQLException: Listener refused the connection with the following error:
ORA-12519, TNS:no appropriate service handler found
The Connection descriptor used by the client was:
localhost:1521:xe
 at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
 at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:116)
 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:177)
And you may see NullPointerExceptions dependent on what ADF was attempting to do with the database connection at the time:
Caused by: java.lang.NullPointerException
 at oracle.adf.model.binding.DCIteratorBinding.initSourceRSI(DCIteratorBinding.java:1735)
 at oracle.adf.model.binding.DCIteratorBinding.callInitSourceRSI(DCIteratorBinding.java:1625)
 ... 75 more
Under JDev 11gR1 build 5407 gives you a more meaningful error message:

Again, first you'll see errors that it can't retrieve user session state:

SEVERE: Could not find saved view state for token -ce0efchp5
11/08/2009 2:35:31 PM org.apache.myfaces.trinidadinternal.application.StateManagerImpl restoreView
SEVERE: Could not find saved view state for token -ce0efchp7
11/08/2009 2:35:31 PM org.apache.myfaces.trinidadinternal.application.StateManagerImpl restoreView
SEVERE: Could not find saved view state for token -ce0efchp7
11/08/2009 2:35:31 PM org.apache.myfaces.trinidadinternal.application.StateManagerImpl restoreView
But then you'll see a much more meaningful message that ADF can't create the required objects:
oracle.jbo.PCollException: JBO-28006: Could not create persistence table PS_TXN_seq
 at oracle.jbo.PCollException.throwException(PCollException.java:36)
 at oracle.jbo.pcoll.OraclePersistManager.createTable(OraclePersistManager.java:908)
 at oracle.jbo.pcoll.OraclePersistManager.queryNextCollectionId(OraclePersistManager.java:1444)
And further down:
Caused by: java.sql.SQLSyntaxErrorException: ORA-01031: insufficient privileges
 at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:91)
 at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:206)
 at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
 at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:413)


Special thanx to Chris Muir for his excellent post.

Dig more:
  • http://chrismuir.sys-con.com/node/1067419/mobile
  • http://download.oracle.com/docs/cd/E12839_01/web.1111/b31974/bcstatemgmt.htm#ADFFD1307

You might also like:

Related Posts Plugin for WordPress, Blogger...