ASP.Net MVC中Donut缓存与Donut Hole缓存相关问题咨询
针对你提出的三个关于ASP.NET MVC中Donut缓存和Donut Hole缓存的疑问,我来逐一拆解说明:
问题1:为什么参考文章中用[OutputCache]而非[DonutOutputCache]实现Donut缓存?
其实核心原因是**DonutOutputCache是第三方扩展(比如MvcDonutCaching库提供的特性)**,而原生ASP.NET MVC的[OutputCache]本身并不支持Donut缓存的特性。那些文章里大概率省略了前提:他们已经通过NuGet安装了MvcDonutCaching库,并且完成了替换原生OutputCache的配置。
具体来说,MvcDonutCaching库会替换默认的OutputCacheAttribute,让你在Action上标记[OutputCache(Duration=60)]时,底层实际跑的是DonutOutputCache的逻辑,从而实现Donut缓存效果。如果没安装这个库,原生的[OutputCache]只会缓存整个Action的输出,做不到排除特定区域的Donut缓存。
问题2:缓存局部视图时,该用OutputCache还是DonutOutputCache?OutputCache会内部调用DonutOutputCache吗?
先理清两个关键点:
- 如果你是用MvcDonutCaching实现Donut Hole缓存(即只缓存局部视图,页面其他部分不缓存),在局部视图对应的Action或视图上标记
[OutputCache]就足够——前提是已经配置了MvcDonutCaching替换原生的OutputCacheAttribute,这时的[OutputCache]就是DonutOutputCache的封装。 - 原生
[OutputCache]直接用在局部视图上,只会缓存该局部视图的输出,但无法实现Donut Hole缓存的核心:父页面不缓存、仅局部视图缓存的效果。
简单说,原生OutputCache不会内部调用DonutOutputCache,只有引入MvcDonutCaching这类第三方库并完成替换配置后,[OutputCache]特性才会被替换为DonutOutputCache的逻辑,从而支持Donut和Donut Hole缓存。
问题3:缓存位置设为客户端时,不同用户访问同一页面会触发数据库查询吗?
当缓存位置(Location)设为Client时,缓存数据是存储在每个用户自己的浏览器本地的:
- 第一个用户访问页面时,服务器会执行数据库查询、生成页面内容,返回给用户的同时,告知浏览器缓存这份内容指定时长(比如60秒)。
- 同一个用户在缓存有效期内再次访问,浏览器直接用本地缓存,不会请求服务器,自然不会触发数据库查询。
- 但其他PC的用户首次访问时,他们的浏览器没有这份缓存,会向服务器发起请求,服务器此时需要重新执行数据库查询、生成页面内容,再返回给该用户并让其浏览器缓存数据。
也就是说,客户端缓存是用户隔离的,每个用户的缓存相互独立,不同用户首次访问都会触发服务器端的数据库查询。
内容的提问来源于stack exchange,提问作者Mist

