When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips

Sections:
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
XML Info
Information:
Feedback
Author an Article
ASP ASP.NET ASP FAQs Message Board Feedback
Print this page.
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!

- continued -

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!


ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article