【问题标题】:Will cached content update when database entries are added?添加数据库条目时缓存的内容会更新吗?
【发布时间】:2015-11-03 21:45:33
【问题描述】:

好吧!我仍在尝试缓存,到目前为止它很棒!关于数据库更新的快速问题。

TLDR:数据库更新何时传播到缓存?如果没有设置Cache过期时间,用户退出再进入应用时是否清除?还是 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');

现在数据库将包含一周中的所有 7 天。下一个页面加载事件会开始新的日子吗?还是会使用缓存的副本,仍然只显示原始的五个?

缓存副本何时(如果有)过期并重新获取所有 7 天?

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

【问题讨论】:

    标签: c# mysql sql asp.net


    【解决方案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);
    

    当缓存依赖中的表发生变化时,缓存会失效并被移除。

    【讨论】:

    • 以前没听说过 AggregateCacheDependency。 This thread 似乎建议它轮询您的数据库以获取数据更改。这会影响数据库性能吗?
    • 我的一般理解是,如果更改频繁,使用 SqlDependency 对性能的影响更大,而如果更改​​不频繁,则使用轮询方法会更好。与大多数事物的性能一样,它归结为衡量任一系统对您的使用需求的影响。
    • 但是,要直接回答您的问题,除非您使用 SqlDependency 或其他方法(例如轮询以查看表是否更改)来删除缓存,否则缓存不会在数据库更新时更新 -当您认为它的数据不再有效时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 2020-06-10
    相关资源
    最近更新 更多