添加数据库条目时,缓存的内容是否会更新?
问题描述:
好吧!至今我仍在尝试缓存及其优点!有关数据库更新的快速问题添加数据库条目时,缓存的内容是否会更新?
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);
当缓存依赖项中的表发生更改时,缓存将失效并被删除。
之前没有听说过AggregateCacheDependency。 [这个线程](https://stackoverflow.com/questions/14203704/using-sqldependency-vs-periodic-polling-of-a-table-performance-impact)似乎表明它轮询你的数据库的数据变化。这会影响数据库性能吗? –
我的一般理解是,如果更改频繁,使用SqlDependency会更多地影响性能,而如果更改不频繁,则轮询方法会更好。正如大多数情况下的表现一样,它将归结为衡量任一系统对您的使用需求的影响。 –
但是,要直接回答您的问题,除非使用SqlDependency或其他方法(例如查询表是否更改)来删除缓存项,否则缓存将不会更新数据库更新不再有效。 –