添加数据库条目时,缓存的内容是否会更新?

问题描述:

好吧!至今我仍在尝试缓存及其优点!有关数据库更新的快速问题添加数据库条目时,缓存的内容是否会更新?

TLDR:数据库更新何时提交给缓存?如果没有设置缓存过期时间,是否清除用户何时退出并重新进入应用程序?或者是HTTPContext.Current.Cache一个全局缓存(即,只有在所有用户退出应用程序时才清除(如果发生的话))?

说我有一个表:

CREATE TABLE #DaysOfTheWeek(
    DayKey INT 
    ,DayDescription VARCHAR(20) 
); 

INSERT INTO #DaysOfTheWeek VALUES(1, 'Monday'); 
INSERT INTO #DaysOfTheWeek VALUES(2, 'Tuesday'); 
INSERT INTO #DaysOfTheWeek VALUES(3, 'Wednesday'); 
INSERT INTO #DaysOfTheWeek VALUES(4, 'Thursday'); 
INSERT INTO #DaysOfTheWeek VALUES(5, 'Friday'); 

我在ASP.NET Web应用程序(.NET 4.5)添加这些到一个下拉列表中。

我觉得这是非常糟糕的代码。不要复制和粘贴这个。它是通向SQL注入的。这应该存储在一个程序中。我是一个坏人。

//On page load. 

private void PopulateDaysOfWeekDropDownList() 
{ 
    var days = new List<ListItem>(); 

    if (HttpContext.Current.Cache["DaysOfTheWeek"] == null) 
    { 
     //Go to the database and get all days. 
     var dt = GetDaysOfTheWeek(); 
     foreach(DataRow row in dt.Rows) 
     { 
      var day = new ListItem(); 
      day.Key = row["DayKey"].ToString(); //Key may not be correct, I'm not using a compiler here. 
      day.Description = row["DayDescription"].ToString(); 
      days.add(day); 
     } 
     HttpContext.Current.Cache["DaysOfTheWeek"] = days; 
    } 
    else 
    { 
     //Retrieve the value from the web cache. 
     days = (List<ListItem>)HttpContext.Current.Cache["DaysOfTheWeek"]; 
    } 

    //Bind the results to the web source. 
    ddlDaysOfWeek.DataSource = days; 
    ddlDaysOfWeek.DataBind(); 
} 


public DataTable GetDaysOfTheWeek() 
{ 
    using (var cnn = new SqlConnection("myConnectionString")) 
    { 
     using (var dt = new DataTable()) 
     { 
      var command = "SELECT DayKey, DayDescription FROM #DaysOfTheWeek WITH(NOLOCK)" 
      using (var cmd = new SqlCommand(command, cnn) { CommandType = CommandType.Text}) 
      { 
       using (var adapter = new SqlDataAdapter(cmd)) 
       { 
        adapter.Fill(dt); 
       }    

       return dt; 
      } 
     } 
    } 
} 

一切都很好。这在我的系统上运行了几天,网络缓存有五天。

比方说,后来我加周末太:

INSERT INTO #DaysOfTheWeek VALUES(0, 'Sunday'); 
INSERT INTO #DaysOfTheWeek VALUES(6, 'Saturday'); 

现在的数据库将包含一周的七天。下一次页面加载事件是否会吸引新的日子?或者它会采取缓存副本,仍然只显示原来的五个?

缓存副本何时(如果曾经)过期并重新提取所有七天?

从系统管理的角度来看,有什么我们可以做的手动重新刷新服务器缓存?

您可以使用SqlCacheDependency。而不是直接分配项目到缓存中,就像你在下面的代码:

HttpContext.Current.Cache["DaysOfTheWeek"] = days; 

你想使用Cache.Insert与添加的依赖。如果缓存取决于多个表,则还可以聚合依赖关系。

var cacheItem = days; 
var tableName = "someTable"; 
var databaseName = "someDb"; 
var cacheKey = "someCacheKey"; 
var aggDependency = new System.Web.Caching.AggregateCacheDependency(); 
aggDependency.Add(new System.Web.Caching.SqlCacheDependency(databaseName, tableName)); 
HttpContext.Current.Cache.Insert(cacheKey, cacheItem, aggDependency); 

当缓存依赖项中的表发生更改时,缓存将失效并被删除。

+0

之前没有听说过AggregateCacheDependency。 [这个线程](https://*.com/questions/14203704/using-sqldependency-vs-periodic-polling-of-a-table-performance-impact)似乎表明它轮询你的数据库的数据变化。这会影响数据库性能吗? –

+1

我的一般理解是,如果更改频繁,使用SqlDependency会更多地影响性能,而如果更改​​不频繁,则轮询方法会更好。正如大多数情况下的表现一样,它将归结为衡量任一系统对您的使用需求的影响。 –

+0

但是,要直接回答您的问题,除非使用SqlDependency或其他方法(例如查询表是否更改)来删除缓存项,否则缓存将不会更新数据库更新不再有效。 –