【问题标题】:How to cache database data into memory for use by MVC application?如何将数据库数据缓存到内存中以供 MVC 应用程序使用?
【发布时间】:2013-06-22 17:40:56
【问题描述】:
我有一个有点复杂的权限系统,它总共使用六个数据库表,为了加快速度,我想将这些表缓存在内存中,而不是在每次页面加载时都访问数据库。
但是,当添加新用户或更改权限时,我需要更新此缓存。我不确定如何在内存缓存中使用它,以及如果在更新的同时访问它,如何安全地更新它而不引起问题
有没有人可以举例说明如何做这样的事情,或者可以为我指出正确的研究方向?
【问题讨论】:
标签:
c#
caching
asp.net-mvc-4
【解决方案1】:
在不了解应用程序结构的情况下,有很多可能的选择。一种这样的选择可能是抽象存储库接口后面的数据访问并处理该存储库中的内存缓存。就像存储库对象上的私有 IEnumerable<T> 一样简单。
例如,假设您有一个 User 对象,其中包含有关用户的信息(名称、权限等)。你会有一个UserRepository,上面有一些基本的获取/保存方法。在该存储库中,您可以维护一个私有静态 HashSet<User>,其中包含已从数据库中检索到的 User 对象。
当您从存储库中获取User 时,它首先检查HashSet 是否有要返回的对象,如果没有发现它从数据库中获取它,则将其添加到HashSet,然后返回它。当您保存 User 时,它会同时更新 HashSet 和数据库。
同样,在不了解代码库和整体设计的细节的情况下,很难给出更具体的答案。不过,这应该是一个足够通用的解决方案,可以在任何应用程序中工作。
【解决方案2】:
我会在您使用它时缓存项目,这意味着在您取回数据时在您的数据层上检查您的缓存是否可用,否则您将转到数据库并在之后缓存结果。
public AccessModel GetAccess(string accessCode)
{
if(cache.Get<string>(accessCode) != null)
return cache.Get<string>(accessCode);
return GetFromDatabase(accessCode);
}
然后我会考虑我的缓存失效策略。您可以按照以下两种方式:
将过期数据设置为 1 小时,然后您只需每小时访问一次数据库。
或者在更新数据时使缓存失效。这肯定是最好的,但有点复杂。
希望对你有帮助。
注意:您可以使用 ASP.NET 缓存或其他解决方案,如 memcached,具体取决于您的基础架构
【解决方案3】:
问题是每次页面加载都会影响数据库,还是连接六个表是问题?
如果只是连接慢,为什么不创建一个数据库表,以一种更容易查询的方式汇总数据?
这样,您只需在每次添加用户或更新权限时更新汇总表。如果您将所有这些分组到一个事务中,您应该不会遇到数据不同步的问题。
【解决方案5】:
您可以使用 ASP.Net 中内置的 Cache 对象。这是一个article,它解释了如何。
【解决方案6】:
我可以建议在Application state object 中缓存这些数据。对于线程安全使用,请考虑使用lock operator。您的代码将如下所示:
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];
}
}