我有一个具有相当慢的搜索功能的ASP.NET网站,我想通过将查询作为缓存键添加到缓存一小时来提高性能:在ASP.NET中正确执行锁定
using System;
using System.Web;
using System.Web.Caching;
public class Search
{
private static object _cacheLock = new object();
public static string DoSearch(string query)
{
string results = "";
if (HttpContext.Current.Cache[query] == null)
{
lock (_cacheLock)
{
if (HttpContext.Current.Cache[query] == null)
{
results = GetResultsFromSlowDb(query);
HttpContext.Current.Cache.Add(query, results, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
else
{
results = HttpContext.Current.Cache[query].ToString();
}
}
}
else
{
results = HttpContext.Current.Cache[query].ToString();
}
return results;
}
private static string GetResultsFromSlowDb(string query)
{
return "Hello World!";
}
}
假设访问者A进行搜索。缓存为空,设置锁定并从数据库请求结果。现在,访问者B带有不同的搜索:在访问者A的搜索完成之前,访问者B是否必须等待锁定?我真正想要的是B立即调用数据库,因为结果会不同,数据库可以处理多个请求 - 我只是不想重复昂贵的不必要的查询。
这种情况下正确的方法是什么?
是真正的查询那么贵和/或网站那么忙,你买不起几多余的重复查询每小时一次? (并且只有在两次或更多次查询几乎同时在缓存过期时同时触发您的方法时,才会出现这种情况。) – LukeH 2011-04-07 09:22:47
如果您的数据库不支持多个读取访问,则可以实施消息查询,以便DB服务A,然后DB服务B ...在服务时检查缓存。 – Winfred 2011-04-07 09:28:05
@LukeH,在那个特定的数据库中发生了很多事情,所以我们可以减轻负担是值得的。 – 2011-04-07 09:28:43