Aug
23

CFOBJECTCACHE: An Inside Look

Posted by Aaron West at 3:30 PM in ColdFusion

Conversations concerning caching mechanisms in ColdFusion are typically not short. This is not only due to the different options developers have in terms of code but also the many different strategies involved in caching and picking the right strategy for each situation. When dealing with query data, developers have two basic choices (these do not include custom caching mechanisms available from other developers): query-based caching, which involves the use of the cachedwithin and cachedafter attributes of the CFQUERY tag and variable-based caching, which involves the use of shared scopes. Each of these two methods cache data in different ways, are cleared/refreshed in different ways and require different levels of developer involvement. At my workplace we use a combination of these two methods depending on each situation and our data storage/caching needs. The other day I was investigating a bit of our code that uses query-based caching to store data in RAM and the CFOBJECTCACHE tag (introduced in ColdFusion 5) to clear the cache when data in the database had changed. Looking at our code I realized I was not 100% clear on how the CFOBJECTCACHE tag worked across multiple applications (on the same CF instance) so I decided to investigate. What follows is a detailed look at how the CFOBJECTCACHE tag works.

First and foremost, the ColdFusion MX 7 docs say the CFOBJECTCACHE tag "clears queries from the cache in the Application scope." Well okay. But what happens if I have more than one application running on my ColdFusion server and both of them use the cachedwithin attribute of the CFQUERY tag to cache data for a specific time period. Will the CFOBJECTCACHE tag clear the queries from cache across all applications on the same CF instance?

Consider the following two applications:

web_root/cfobjectcache/
............clearCache.cfc

web_root/cfobjectcache/app1/
............Application.cfc
............clearCache.cfm
............index.cfm

web_root/cfobjectcache/app2/
............Application.cfc
............clearCache.cfm
............index.cfm

Click here to download the code. You'll need to alter the index.cfm templates to work with an existing database or create the necessary Widgets table. You'll also need to change the datasource to one valid for your system or create the "Playground" datasource.

Each application in this example runs in its own folder and has its own Application.cfc. Both apps run inside the "cfobjectcache" folder that does not define an application. The clearCache.cfm template, present in all folders, has the same line of code in all cases:

<cfobjectcache action="clear">

The index.cfm template in app1 looks like this:

<cfquery name="qryGetData" datasource="Playground" cachedwithin="#CreateTimeSpan(0,0,3,0)#">
   SELECT W.ID, W.WidgetName, W.WidgetDesc, W.DateAdded, W.DateLastUpdated
   FROM Widgets W
   WHERE W.ID = 2
   ORDER BY W.DateAdded
</cfquery>

<cfdump var="#qryGetData#">

The index.cfm template in app2 looks like this:

<cfquery name="qryGetData" datasource="Playground" cachedwithin="#CreateTimeSpan(0,0,3,0)#">
   SELECT W.ID, W.WidgetName, W.WidgetDesc, W.DateAdded, W.DateLastUpdated
   FROM Widgets W
   ORDER BY W.DateAdded
</cfquery>

<cfdump var="#qryGetData#">

The basic idea is we have two applications, each caching a query for 3 minutes. There's a CFOBJECTCACHE tag in the root folder and each of the application folders that, when called, clears cached queries. If you were to access both index.cfm templates in the applications each query would be cached in RAM for 3 minutes. I quickly discovered that hitting the clearCache.cfm templates in any of the folders would clear all cached queries on the ColdFusion instance. It doesn't matter that each query resides in it's own defined application. For me, this is fine but I can certainly see how having cachedwithin cached queries reside in their own application would be beneficial. Of course, most people would just tell you to cache your queries in the Application scope and manage data storage and expiration on your own. That makes perfect sense, but I do think it would be helpful to have a mechanism of clearing query-based cache by application and not just globally.

Aaron West's Gravatar
About this post:

This entry was posted by Aaron West on August 23, 2006 at 3:30 PM. It was filed in the following categories: ColdFusion. It has been viewed 5918 times and has 2 comments.

2 Responses to CFOBJECTCACHE: An Inside Look

  1. Todd

    I guess I'm a little confused as to whats handling this behaivor. I understand the <cfobjectcache action="clear"> by default clears the cache on the entire server, but are you saying it only clears it for the specific Application.cfc for which it is run under. So if I create a seperate application.cfc for my apps it will clear only their cache?

    Looking forward to your response.

  2. @Todd, the CFOBJECTCACHE tag will clear /all/ queries stored in memory on /any/ Application that has been defined for the server or ColdFusion instance (on a multi-instanced setup).

    If you want to manage query cache at the Application level you'll need to use variable-based caching instead of query-based caching.