Programming Microsoft ASP.NET 4 - Dino Esposito [387]
Taking Advantage of SQL Server Dependencies
The SqlCacheDependency class has two constructors. The first takes a SqlCommand object, and the second accepts two strings: the database name and the table name. The following code creates a SQL Server dependency and binds it to a cache key:
protected void AddToCache(Object data)
{
var database = "Northwind";
var table = "Customers";
var dependency = new SqlCacheDependency(database, table);
Cache.Insert("MyData", data, dependency);
}
protected void Page_Load(Object sender, EventArgs e)
{
if (!IsPostBack)
{
// Get some data to cache
var data = Customers.LoadByCountry("USA");
// Cache with a dependency on Customers
AddToCache(data);
}
}
The data in the cache can be linked to any data-bound control, as follows:
var data = Cache["MyData"] as IList if (data == null) Trace.Warn("Null data"); CustomerList.DataTextField = "CompanyName"; CustomerList.DataSource = data; CustomerList.DataBind(); When the database is updated, the MyData entry is invalidated and, as in the sample implementation provided here, the list box displays empty. Important You get notification based on changes in the table as a whole. In the preceding code, we’re displaying a data set that results from the following: SELECT * FROM customers WHERE country='USA' If, say, a new record is added to the Customers table, you get a notification no matter what the value in the country column is. The same happens if a record is modified or deleted where the country column is not USA. By using a SqlCommand object in the constructor of the dependency class, you gain a finer level of control and can notify applications only of changes to the database that modify the output of that specific command. Distributed Cache The need to “re-create” the last known good state results in an additional workload that saturates Web and data servers quite soon and kind of linearly as the number of users increases. Caching is a way to smooth the issue by providing a data store that sits nearer to the user and doesn’t require frequent roundtrips to central servers. The ASP.NET Cache object has a number of powerful and relevant capabilities. Unfortunately, today’s business needs raised the bar a little higher. As a result, the Cache object is limited today because it is bound to a worker process and a single machine. The Cache object doesn’t span multiple machines like in a Web farm; its amount of memory affects only a single machine and can’t be scaled out horizontally. Enter distributed caching. The power of a distributed cache is in its design, which distributes load and data on multiple and largely independent machines. Implemented across multiple servers, a distributed cache is scalable by nature but still gives the logical view of a single cache. Moreover, you don’t need high-end machines to serve as cache servers. Add this to cheaper storage and faster network cards and you get the big picture—distributed caching these days is much more affordable than only a few years ago. Figure 18-3 shows the abstraction that a distributed caching layer provides to applications. Figure 18-3. Overall design of a distributed cache. Note In a previous edition of this book, in the same chapter about caching, I had arguments against the widespread use of a distributed cache. Only a few years ago, the perception of scalability was different. It was recognized as a problem, but most of the time it could be
Scalability is an aspect of software that came with the advent of successful Web applications. It is strictly related to the stateless nature of the HTTP protocol so that any new requests from the same user in the same session must be bound to the same “state” left by the last request.