2015-11-03 50 views
1

好吧!至今我仍在嘗試緩存及其優點!有關數據庫更新的快速問題添加數據庫條目時,緩存的內容是否會更新?

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'); 

現在的數據庫將包含一週的七天。下一次頁面加載事件是否會吸引新的日子?或者它會採取緩存副本,仍然只顯示原來的五個?

緩存副本何時(如果曾經)過期並重新提取所有七天?

從系統管理的角度來看,有什麼我們可以做的手動重新刷新服務器緩存?

回答

1

您可以使用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://stackoverflow.com/questions/14203704/using-sqldependency-vs-periodic-polling-of-a-table-performance-impact)似乎表明它輪詢你的數據庫的數據變化。這會影響數據庫性能嗎? –

+1

我的一般理解是,如果更改頻繁,使用SqlDependency會更多地影響性能,而如果更改​​不頻繁,則輪詢方法會更好。正如大多數情況下的表現一樣,它將歸結爲衡量任一系統對您的使用需求的影響。 –

+0

但是,要直接回答您的問題,除非使用SqlDependency或其他方法(例如查詢表是否更改)來刪除緩存項,否則緩存將不會更新數據庫更新不再有效。 –

相關問題