Now, what I intend to do is as soon as user requests for this page, queries are executed, beans are loaded and placed in arraylist and arraylist is
cached at application and not session scope.Next time user requests the page, certain queries are performed to determine validity of existing cache. If
cache is valid, just use the same cache instead of generating a new report.
I have following configuration in dispatcher-servlet.xml:-
where TestController1 extends SimpleFormController..
I intend to use below approach in my TestController class:-
I have a TestControllerOutput Class
and then there is CacheBean class which actually contains data....
Now my approach is to have 1 instance of CacheBean used by 1 instance of TestControllerOutput and
I believe from above approach, TestController1 will give same instance of TestControllerOutput to every threads.
I wouldn't put the synchronize in the model view part
That will lock that bit of code regardless if the report is being generated
I would do something like:
Then the getReport metod would be more like
You could have an updateReport method which could be called every time you need an update. That could run in the background every so many minutes and update the tcoReport array. This minimizes the amount of time threads would wait for a lock release.
Joined: Jul 02, 2009
thanks Gerardo..This is a very efficient approach..However, I feel wrt my app, I might face some implementation difficulties...
1) I will give a brief explanation on this. Whether to update cache or not is decided by query and not by time.
The first query gives me a series of numbers like resulset row1-> 56, resultset row2-> 34 and so on. Everytime I take the count of rows that has value greater then cache's max value..eg 56 here. If count is more then zero, that means report needs to be updated.
So, I was thinking that with every request, this query should be executed. So essentially I want to execute this query before "getReport" for every request.something like
But then, it will again increase amont of time threads have to wait. The database operations are such that there are fewer inserts/updates but more reads.
So, in this case is this approach more feasible or running "updateReport" in background? Also, how do I run "updateReport" in background in spring? I guess I would have to implement "updateReport" in class that extends Runnable or something like that.
2) You also mentioned in TestControllerServlet:-
I guess, here "tcoReport" and "tco" are class level variables and not local variables inside "onSubmit" method. Essentially, I will be using
same instance of "TestControllerOutput" ie tco for every requests. Am I right?
Sorry for a very long post.
Joined: Feb 08, 2005
Quick note tcoReport is method scope and tco is class scope. You don't want multiple treads reading and writing to tcoReport.
Regarding your question. I'm under the impression that the INSERTs and UPDATEs are the ones that eventually lead to cache update. What you can do is check after an insert/update is done and verify if an update needs to be done. That would lead to some bottleneck in the inserts/updates, but you say it is less common. So it would be less impacting.
The other option is to run updates from a separate thread. This thread wakes up on every insert and does the job while the insert process is freed to continue accepting inserts.
Joined: Jul 02, 2009
My webapp does not allow inserts or updates...The db inserts/updates take place at a different facility which is completely independent
of this webapp and I cannot modify anything inside db schema....So when you said:-
What you can do is check after an insert/update is done and verify if an update needs to be done
This thread wakes up on every insert and does the job while the insert process is freed to continue accepting inserts.
you meant writing some kind of database triggers, which I am not allowed to modify. I dont see any other way in which insert or update in db can trigger a thread.
Your approach has proved a good learning experience for me.
Joined: Feb 08, 2005
In that case I'd set up a thread that periodically checks to see if the cache needs to be updated. Since there is no way to know if the cache is needed and for a period of time no read requests might arrive, you run the possibility of having your data not refresh for a while. And the first read request that comes in will take a while to respond. Based on your experience you can set the system to check every minute, 5 minutes or whatever you see fit. If an update is needed then you just fire the method and go to sleep again. That will make your application seem responsive for all requests.