--
--
You received this message because you are subscribed to the ADF Enterprise Methodology Group (http://groups.google.com/group/adf-methodology). To unsubscribe send email to adf-methodolo...@googlegroups.com
All content to the ADF EMG lies under the Creative Commons Attribution 3.0 Unported License (http://creativecommons.org/licenses/by/3.0/). Any content sourced must be attributed back to the ADF EMG with a link to the Google Group (http://groups.google.com/group/adf-methodology).
---
You received this message because you are subscribed to the Google Groups "ADF Enterprise Methodology Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to adf-methodolo...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
We did more testing on AM's "Disconnect Application Module Upon Release" setting and I need to rectify my previous statement:
On Wednesday, September 11, 2013 3:46:28 PM UTC+1, Florin Marcus wrote:
If going jbo.doconnectionpooling = true way, there will be no re-querying when scrolling an af:table.
Testing showed that scrolling indeed produces re-querying, as follows:
Take the following use case:
Step 1.User opens a page containing an <af:table>.
Step 2.User scrolls down though the results
This would translate to JDBC API level as follows:
Step1: User opens a page containing an <af:table>.
java.sql.Connection conn1 = ...........get connection from the pool.....
java.sql.PreparedStatement pstm1 = conn1.prepareStatement(.....)
java.sql.ResultSet rs1 = pstm1.executeQuery(.....)
rs1.close()
pstm1.close()
conn1.close()
Step2: User scrolls down though the results
java.sql.Connection conn2 = ...........get connection from the pool.....
java.sql.PreparedStatement pstm2 = conn1.prepareStatement(.....)
java.sql.ResultSet rs2 = pstm2.executeQuery(.....)
rs2.close()
pstm2.close()
conn2.close()
So, indeed, there is a query overhead when scrolling, but how much this weights, really?
In practice, since the scrolling fires the same query second time, it will execute much faster because of the database buffer cache. From the test case, if first query took 77 milliseconds to run, the second one (when scrolling) took a millisecond (this numbers may be specific to my test case, though).
Another consequence worth mentioning: when scrolling from 26th to 50th record, the JDBC ResultSet will fetch 50 records, starting from the first. This makes sense, since the ResultSet is re-created, therefore re-iterated.
In conclusion, while "Disconnect Application Module Upon Release" looks worse on paper than default AM connection management, stress tests on various ADF applications showed that it is faster and more scalable. Though, I wouldn't say to take the above statements for granted, but to issue a series of stress testing (e.g. JMeter) along with monitoring your server (e.g. JRockit Mission Control), then see which of the configurations works better for you.
That being said, we are eagerly waiting for Oracle to have a release on jbo.ampool.connection_threshold property, which should hopefully provide us "the best of both worlds" solution.
--
Hi Chris, sorry for the delayed response, last weeks have been very busy.
I see that the use of "Disconnect Application Module Upon Release" still brings a lot of questions and rightfully so, since while being a 'tolerated' practice, it is not ideal, according to Oracle documentation: http://docs.oracle.com/cd/E24382_01/web.1112/e16182/bcampool.htm#sm0301. In the below lines, I will try to explain why the above recommendations may raise a few eyebrows to someone understanding JDBC.
If you look at an ADF application from runtime perspective, you have one servlet (FacesServlet) executing JDBC statements against a database, as many other JEE applications. What is specific about ADF in relation with JDBC is the lifecycle of its prepared statements.
The main idea behind ADF in relation to JDBC is that once a connection is acquired, it stays sticky across requests. This allows keeping Prepared Statements open, minimising the overhead of re-creating and closing the same statements across subsequent accesses - thereby providing the best performance. On the other hand, when using "Disconnect Application Module Upon Release", at the end of each request the connection is released back to the pool and the statements are closed - therefore such option shouldn't be used unless limiting the number of database connections is a priority. That's shortly the theory, but in reality there is much more to it.
Statement Caching Levels
An ADF application benefits of three levels of statement caching :
1. BC statement cache
2. JDBC Datasource statement cache
3. Oracle Server statement pool (SGA)
Here is a short description of each pool level:
1. BC Statements Cache (as it works with 11g both Release 1 and Release 2 )
Anyone having access to ADF sources can observe this implementation on oracle.jbo.ViewObjectImpl source file. With the additional help of excellent JDeveloper Memory Profiler and JRockit Mission Control, we had a closer look at how this pool works:
Each view object instance caches its Prepared Statements. It worth mentioning that a view object's query may change at runtime, therefore there can be more than one PreparedStatement for each instance. For example, in simplest scenario involving an <af:table>, on first rendering you will get one PreparedStatement in cache. If you re-order your columns, you will already have two PreparedStatements, furthermore, when you filter by a column you will get a third PreparedStatement. The main benefit is that a PreparedStatement will be reused as long as the user keeps repeating the same actions.
2. JDBC Statements Cache
Introduced as a standard in version 3.0, JDBC statement pool works in a similar fashion as connection pooling does. To understand this functionality, a distinction must be made between logical and physical prepared statements. When a developer creates a logical prepared statement by calling java.sql.Connection.prepareStatement() method, the driver will try to find a corresponding physical statement in the pool. Furthermore, when calling java.sql.PreparedStatement.close() method, the logical statement will close, but the physical statement will go back into the pool. It is also important to note that by calling java.sql.Connection.close() method, the physical statement cache won't be cleared, since is associated with the physical connection being returned back to connection pool.
Our tests showed that disabling JDBC cache didn't bring any notable performance decrease. This is due to more powerful Oracle Server caching mechanism that spans across sessions. However, it will save you few roundtrips - important when the network connection between Weblogic Server and Oracle Server is not too fast.
3. Oracle Server Statement Pool (SGA)
This cache is called the library cache and located in the shared pool of the Oracle server’s System Global Area (SGA). When a SQL statement is submitted, the server first checks the library cache to see if an identical statement is already present in the cache. If it is, Oracle uses the stored parse tree and execution path for the cached statement, rather than rebuilding these structures from scratch.
BC Statements Cache - memory hungry
With default settings, an ADF application will consume more server memory by of holding PreparedStatements open, especially for Oracle's JDBC driver implementation, where T4CPreparedStatement is a fairly large object, as reported by Memory Profiler tools. Closing prepared statements programatically doesn't mean closing the physical statement, but returning the physical statement back to the pool for later reuse. Moreover, there is less reuse of physical Statements, since the BC Pool is limited to View Object instances and will basically suppress the use of JDBC statement pooling. On the database side, there it will be a higher number of opened CURSORS and consequently a smaller CURSOR reuse rate (session cursor cache hits) - how this can affect the database server performance? This we leave for the database specialists.
Probably the BC statement pooling was implemented prior to JDBC statement cache, so it may require a revisit. The only benefit it brings relates to a more effective scrolling by caching ResultSet objects, on the other hand it consumes more memory on Weblogic and produces a higher number of opened cursors on the database.
In conclusion
The real power sits behind Oracle Server caching, the other two caching levels are less significant.
What we do hope is that Oracle best practice tips can be revised in the sense of bringing more justice to "Disconnect Application Module Upon Release" alternative. It will make our job more easier when recommending this solution to our customers.
Thanks,
Florin Marcus
www.redsamuraiconsulting.com