如何将数据库数据缓存到内存中供MVC应用程序使用?

5
我有一个相对复杂的权限系统,使用了6个数据库表。为了加速系统运行,我希望将这些表缓存到内存中,而不是每次页面载入时都要访问数据库。
然而,当添加新用户或更改权限时,我需要更新这个缓存。我不确定如何在内存缓存中安全地进行更新,以避免同时访问和更新导致问题。
请问是否有类似的操作示例,或可以指引我进行相关研究的方向?

缓存6个表看起来不是一个好主意。 - Big Daddy
C#/.Net中的缓存的重复问题 - Dustin Kingen
6个回答

2
不了解应用程序的结构,有很多可能的选择。其中一种选择可能是在存储库接口后面抽象数据访问,并在该存储库中处理内存中缓存。可以将一个简单的私有 IEnumerable<T> 放置在存储库对象上。
例如,假设您有一个包含用户信息(名称、权限等)的User对象。您将具有一个UserRepository,其中包含一些基本的获取/保存方法。在该存储库内部,您可以维护一个私有静态 HashSet<User>,其中包含已从数据库检索的User对象。
当您从存储库中获取User时,它首先检查HashSet以返回对象,如果没有找到,则从数据库获取它,将其添加到HashSet,然后返回它。当您保存User时,它会更新HashSet和数据库。
同样,如果不了解代码库和整体设计,很难给出更具体的答案。但这应该是一个通用的解决方案,适用于任何应用程序。

1
我建议您在使用时缓存项目,这意味着在数据层中获取数据时,先检查缓存是否可用,否则再从数据库获取,并在此之后将结果缓存。
public AccessModel GetAccess(string accessCode)
{
     if(cache.Get<string>(accessCode) != null)
          return cache.Get<string>(accessCode);

     return GetFromDatabase(accessCode);
}

接下来我会考虑我的缓存失效策略。你可以采用两种方式:

一种是将过期数据设置为1小时,然后每小时只需从数据库中获取一次。

或者在更新数据时使缓存失效。这肯定是最好的方法,但稍微复杂一些。

希望能有所帮助。

注意:你可以使用ASP.NET Cache或其他解决方案,如memcached,具体取决于你的基础设施。


0

是每次页面加载都访问数据库的问题还是连接六个表的问题?

如果只是连接速度慢,为什么不创建一个数据库表,以更轻松、更快速的方式汇总数据呢?

这样,您只需在添加用户或更新权限时更新摘要表。如果将所有内容分组到单个事务中,就不应该出现数据不同步的问题。


0
你可以利用ASP.NET缓存和SqlCacheDependency类。这里有一个关于MSDN的文章article on MSDN

0

你可以使用内置于ASP.Net中的Cache对象。这里有一篇文章,解释了如何使用它。


0

我可以建议将这些数据缓存到应用程序状态对象中。为了线程安全,可以考虑使用锁操作符。你的代码会像这样:

public void ClearTableCache(string tableName) 
{
    lock (System.Web.HttpContext.Current) 
    {
       System.Web.HttpContext.Current.Application[tableName] = null;
    }        
}

public SomeDataType GetTableData(string tableName) 
{
    lock (System.Web.HttpContext.Current) 
    {
       if (System.Web.HttpContext.Current.Application[tableName] == null) 
       {
          //get data from DB then put it into application state
          System.Web.HttpContext.Current.Application[tableName] = dataFromDb;
          return dataFromDb;
       }
       return (SomeDataType)System.Web.HttpContext.Current.Application[tableName];
    }            
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接