How CommandNotification works with OutputCaching

Onion Blog

Syndication

There is some magic to the way SQL Server 2005 cache dependencies work with the OutputCache directive, and I finally had the chance to dig a little deeper and find out exactly what that magic was, so I thought I'd post about it here in case anyone else is interested.
 
The rationale behind SQL cache dependencies with output cached pages is that you may want a page to be flushed from the cache if the underlying data that was used to generate the page has changed. With SQL 7/2000 cache dependencies, you must install a script in your database, set up a configuration file entry, and then specify exactly which tables should be monitored in the SqlDependency attribute of the OutputCache directive to enable the dependency checking. For example, if we knew that a page depended on the authors and publishers tables in the pubs database, we might have an output cache directive that looked like:
 
<%@ OutputCache Duration="3600" SqlDependency="pubs:authors,pubs:publishers" VaryByParam="none" %>
 
This technique relies on the ASP.NET worker process to poll the database at a periodic interval checking a 'change' table that keeps track of when tables change.
 
When you are using SQL Server 2005, however, you can use the notification service along with Service Broker to asynchronously call back into the ASP.NET worker process and signal that the an item in the cache is no longer valid. What's interesting about using this with output caching is that you need do nothing more than specify the string "CommandNotification" in the SqlDependency attribute, and it "just works" (well, as long as the queries are somewhat constrained and everything is properly set up in SQL 2005...).
 
<%@ OutputCache Duration="3600" SqlDependency="CommandNotification" VaryByParam="none" %>
 
This was the part I've always wondered about - how did they instrument all of the SQL queries on a page to enable notifications and tie them to the cache entry for that output cached page? It turns out that when you mark a page as output cached and set SqlDependency to CommandNotification the page sets a flag in the call context (yes, the same call context you may know from remoting - System.Runtime.Remoting.Messaging.CallContext) called "MS.SqlDependencyCookie". The name actually threw me for a bit, because I began looking for an HTTP cookie with that name and couldn't find one (which was good news - that would have been a major hack :). Anyway, if this cookie is set, the SqlCommand class will automatically create a SqlDependency object and attach it to any queries made, tied to the cache key for the output cached page (the key is stored as a value in the cookie). The end result is that every single SqlCommand used on a page that is output cached and has the SqlDependency set to "CommandNotification" will automatically be issued with a SqlDependency requesting a notification on change.
 
The advantage of this technique is that it is so easy to take advantage of - just write your page like you always would, with either declarative SqlDataSource controls or dynamic queries coded by hand, and all of your commands will automatically be set up with notifications. The drawback is that you don't have any finer-grained control over which data access should trigger a notification and which should not (at least that I could find). Also, if any of the queries in your page do not meet the requirements for SQL 2005 cache dependencies (like using SELECT * or simple table names (authors instead of dbo.authors) ), the page will never be cached at all.
 
 

Limited training time? Need to learn ASP.NET 2.0 and SQL Server 2005?
Come join Fritz Onion and Dan Sullivan the week of July 17, 2006 in Waltham, MA for a
Pluralsight Double Feature: ASP.NET 2.0 and SQL Server 2005
Register today!


Posted Jun 15 2006, 09:26 AM by fritz-onion
Filed under:

Comments

Craig wrote re: How CommandNotification works with OutputCaching
on 06-15-2006 9:15 AM
Wouldn't disabling the cookie for the duration of queries you don't want watched provide finer-grained control? I imagine something like this:

using (new NoTrackContext())
{
reader = cmd.ExecuteReader();
}
Fritz Onion wrote re: How CommandNotification works with OutputCaching
on 06-15-2006 9:52 AM
Yeah, that should do the trick - thanks Craig. If anyone actually does this, be sure to *heavily* comment it, because no one will know what the heck you're doing otherwise :)



Jason Haley wrote Interesting Finds: June 15, 2006 PM edition
on 06-15-2006 6:07 PM
Christopher Steen wrote Link Listing - June 18, 2006
on 06-18-2006 7:29 PM
[Cool Tool]Unlocker : Unlock Files/Folders without going
nuts [Via: RoyOsherove ]
Awesome Firefox...
Deepak Chawla wrote re: How CommandNotification works with OutputCaching
on 07-16-2006 7:08 AM
Failing the output cache when the data is redundant which makes the page is a good idea but seems difficult to implement.

I can add that I have seen your webcasts for 2.0 webcasts ( 15th ) even in your demo this section failed to work.

I have tried using your Lab session I still get the problem with Lab15 Part-2 "Output caching with SQL cache invalidation" The page does refresh for even though the cache is not valid.

That made me go mad and I went through every webcast of microsoft.com for sqlcache and output cache and not even a single one I've seen working. Surprisingly even those guys don't have the samples on their blogs for the webcasts. :(

Any ideas reply to webdeepak@hotmail.com
Schuco wrote re: How CommandNotification works with OutputCaching
on 01-25-2008 12:32 AM
How dows "MS.SqlDependencyCookie" work for multiple notifications ??
You can get a notification only once, then you have to recreate the dependency, and also recreate Commands and so on ( I'm using a DataContext, and only want to refresh data )

Any ideas ?

Add a Comment

(required)  
(optional)
(required)  
Remember Me?