Published: Friday, November 10, 2000
A Real-World Example of Caching Data in the Application Object
| Interested in Caching? |
|
Interested in learning more about caching? Check out our recently added
Caching Article Index! There you'll
find links to great articles all over the Web on utlizing caching techniques!
|
I (Scott Mitchell) recently tweaked the
ASPMessageboard homepage so that
the database values displayed are cached (as opposed to needing to make a call to
the database each time the homepage is visited). The front page on the messageboard
shows the number of posts for each forum in a given day... (If you're not familiar
with the messageboard's front page, take a moment to
check it out!).
Before my recent change, the front page made a database call each time it was viewed.
The database call grabbed the number of daily posts and total posts for each forum
(as well as for the entire messageboard). The front page is the ASPMessageboard's
second most-visited page (after the ASP
Q&A Forum), so I reasoned that I could remove a little bit of stress on the
database by caching the various forum post counts as opposed to grabbing them every
single page request.
For this project I decided to cache my data as application-level variables. There are a
number of methods you can choose to use when it comes to caching data... there are
third-party components avaiable, for example. In my opinion, using the Application
object is the simplest and makes the most sense. (With
ASP+ there is a built-in Caching object that
you can use!)
As with any caching technique, you need to decide what event invalidates the cache.
For this project, I decided to have it be time-based: if it had been more than 15 minutes
since I last cached, I invalidated the cache, and hit the database, reloading the cache.
To start, I needed an application-level variable to keep track of the last time the
cache was created: DateCached. Second, I needed to initialize the variable in the Global.asa
file's Application_OnStart event handler. Obviously, I need the cache to
be invalid when the messageboard's front page is hit for the first time after a server
restart. Therefore, I have the DateCached application variable initialized
to one day prior to the current time:
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart
'Initialize the DateCached application variable to
'one day prior to the current date/time
Application("DateCached") = DateAdd("d", -1, Now())
End Sub
</SCRIPT>
|
For more information on DateAdd check out this popular FAQ:
How can I add or subtract time from a date?
For more information on Global.asa be sure to read:
Everything you Wanted to Know about Global.asa,
but Were Afraid to Ask!
Now, in the front page for the messageboard (Default.asp), I needed to
first determine if the cache was invalid (i.e., the difference between the current
time and the Application("DateCached") variable was greater than 15
minutes). If it was, then I needed to hit the database and populate the various
application-level variables with the results. If the cache was not invalid,
then I simply needed to display the cached data.
To determine if my cache is invalid, I use this simple conditional:
If DateDiff("n", Application("DateCached"), Now()) > 15 Then
|
This statement uses the VBScript DateDiff function to determine the time
between the DateCached application variable and the current time.
If this conditional is true (that is, the time between our last cache operation and
the current time exceeds 15 minutes), then we need to hit the database and repopulate
the cache like so:
Application.Lock 'Lock the application object
If DateDiff("n", Application("DateCached"), Now()) > 15 then
'******* Cache is invalid!! *********
'We need to repopulate the cache...
'Make connection to database
Dim objConn
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "DSN=Foo"
'Get the post Count
Dim objRS
Set objRS = objConn.Execute("sp_GetPostCount")
'Now, set the application level cache to the
'database results
Application("iTotal") = objRS("TotalPosts").Value
Application("iASP") = objRS("ASPPosts").Value
Application("iDatabase") = objRS("DatabasePosts").Value
' ... some code snipped for brevity ...
' **** VERY VERY IMPORTANT!! ****
'We must now update the time with which we last
'cached our data!
Application("DateCached") = Now()
End If
Application.UnLock 'Unlock the application object
|
Note that we are setting a slew of application-level variables to database results.
These are displayed further down in our ASP page, where the HTML is outputted displaying
the post counts for each forum for the day. Note that we don't need to do anything if
the cache is valid... we already have the cached database results!
Note that we use the Lock method of the Application object
before we check to see if the cache valid or not... furthermore, we UnLock
the cache once we've completed this step. When the Application object
is locked, no other concurrent users can access application-level variables until
it is unlocked. Therefore, we prudently Lock the Application
object before altering its values.
The Default.asp page concludes with the HTML output that integrates
the various application-level variables:
... some HTML removed for brevity ...
<li><a HREF="/forum/asp.asp">ASP Questions and Answers</a>
(<%=FormatNumber(Application("iASP"),0)%> new posts today<br>
<li><a HREF="/forum/ASPPlus.asp"><b>Moderated</b> ASP+ Forum</a>
(<%=FormatNumber(Application("iASPPlus"),0)%> new posts today<br>
<li><a HREF="/forum/databases.asp">Database (ADO/SQL/Access) Questions
and Answers</a> (<%=FormatNumber(Application("iDatabase"),0)%>
new posts today, <%=FormatNumber(iDatabaseTotal,0)%> total!)<br>
... some HTML removed for brevity ...
<font size=2><i>
Last cached on <%=Application("DateCached")%>
</I></font>
|
Well, that about wraps it up! In this article we examined how to use the Application
object to cache data. On several sites there's no real need to hit the database everytime,
especially if the values change infrequently.... simply cache the data in application-level
variables! All you need to do is decide how to invalidate the cache, and write a small
bit of code! (To learn more about caching, be sure to check out the
Caching Article Index!)
Happy Programming!