This post is not about a bug, but rather about hidden underwater stone to avoid. Based on my previous use case for WebLogic Stuck Thread - Reproducing WebLogic Stuck Threads with ADF CreateInsert Operation and ORDER BY Clause, I will describe one more possible scenario for the same issue. This will be related to ADF BC API misuse, often it is unclear what side effect could produce at first friendly looking method. This method - getRow(key).
Please download complete sample application, if you are interested to reproduce it in your environment - LargeFetchApp_v3.zip.
This sample provides a method to generate dummy data for regions, around 10000 rows. View Object is using ORDER BY to display records in ascending order:
There is custom method created in AM implementation class. This method is calling ADF BC API getRow(key) method. Nothing dangerous at first, but here I'm using a key of the last record from the rowset - 10099. You may think, this is just a method to get a row by key. Yes true, but what it does for you - before returning one row by key, it will fetch all rows until this row into memory. It travels through each row one by one, until it gets a row with defined key. This may consume a lot of memory, especially if rowset is large and row with defined key is somewhere at the end of the rowset. Example of such method:
Make sure ADF Logger config is enabled for RegionsViewImpl class:
Press Get Row button to invoke our custom method from above:
You will see - all rows are fetched and loaded into memory, before desired row is located:
If there will be concurrent users executing the same operation, sooner or later there will be Stuck Thread created in WebLogic and application will hang.
By the way, same applies for Last button use case in ADF, you should never use Last button - operation Last is going to fetch all rows in between, until it will get to the last row in the rowset.
Please download complete sample application, if you are interested to reproduce it in your environment - LargeFetchApp_v3.zip.
This sample provides a method to generate dummy data for regions, around 10000 rows. View Object is using ORDER BY to display records in ascending order:
There is custom method created in AM implementation class. This method is calling ADF BC API getRow(key) method. Nothing dangerous at first, but here I'm using a key of the last record from the rowset - 10099. You may think, this is just a method to get a row by key. Yes true, but what it does for you - before returning one row by key, it will fetch all rows until this row into memory. It travels through each row one by one, until it gets a row with defined key. This may consume a lot of memory, especially if rowset is large and row with defined key is somewhere at the end of the rowset. Example of such method:
Make sure ADF Logger config is enabled for RegionsViewImpl class:
Press Get Row button to invoke our custom method from above:
You will see - all rows are fetched and loaded into memory, before desired row is located:
If there will be concurrent users executing the same operation, sooner or later there will be Stuck Thread created in WebLogic and application will hang.
By the way, same applies for Last button use case in ADF, you should never use Last button - operation Last is going to fetch all rows in between, until it will get to the last row in the rowset.
Nice One!!!!
ReplyDeleteHi Andrejus,
ReplyDeleteWhat's the best solution to get one row by key? Create a view criteria based on the id or use the method findByKey(myKey, 1)?
Regards
I will post update for this soon and let you know.
ReplyDeleteAndrejus
Sebastien, I have posted update to your question here: http://andrejusb.blogspot.com/2013/11/find-by-key-and-view-criteria-row.html
ReplyDeleteAndrejus
Thank you!
ReplyDeleteSébastien
There is a greater hidden stone or shall I see landmind caused by calls to getRow done by ADF after passivation when a new row is and a passivation/activation event occurs immediately after. It has the potential to bring your system down as it did in our case. I blogged about it here.
ReplyDeletehttp://dkleppinger.blogspot.com/2012/04/danger-of-using-default-settings-of.html
Download of application zip file is failing with 404 error - The requested URL /files/LargeFetchApp_v3.zip was not found on this server. Could you please restore the link and make the application available so that we can reproduce the issue? Thanks.
ReplyDeleteYou can download all old samples from Google Archive: https://code.google.com/archive/p/jdevsamples/downloads
ReplyDeleteRegards,
Andrejus
You made my day.. , "getRow" method was killing our system at multiple places when our application is very data intensive ... some tables have more than 300 million rows in database.
ReplyDeleteAwesome :)
ReplyDelete