spring緩存

5.7  緩存

在很多程序裏,讀取數據的頻率比寫入要高得多。比如RoadRantz,訪問站點來查看帖子的人比張貼帖子的人要多。雖然帖子列表會隨着時間不斷增長,但其增長速度比不上被查看的速度。

更進一步說,RoadRantz所展示的數據對於實時性要求並不高。如果用戶在訪問站點時看到了稍微過時一點的帖子列表,並不會產生太多負面影響,他們會稍後再返回站點來查看更新的帖子列表,這樣做並不會有太大問題。

儘管如此,DAO每次收到關於帖子列表的請求時,都會訪問數據庫來獲得最新的數據(經常會得到與上次請求一樣的數據)。


數據庫操作通常都是程序性能的最大瓶頸。對於負載很大的程序來說,針對高度優化的數據源進行的最簡單查詢都可能會產生性能問題。


均衡考慮數據變化的頻率以及查詢數據庫所付出的性能代價,總是從數據庫獲取最新數據似乎並不明智,而對頻繁訪問(但不頻繁更新)的數據進行緩存則顯得更加合理。

從表面上看,緩存似乎相當簡單:在獲取一些信息之後,把它保存到本地(和更便於訪問的)位置,從而便於下次需要時使用。但是,手工實現緩存是很麻煩的。以HibernateRantDao的getRantsForDay()方法爲例:

   

這個方法就非常適合緩存。我們不可能讓時間倒轉,到過去的某一天來添加帖子。只要被查詢的不是今天,對其他任意一天進行查詢而返回的帖子列表都是一樣的,也就沒有必要總是對數據庫進行操作來返回過去某一天的帖子列表。我們只需查詢數據庫一次,然後就可以記住結果,以備下次查詢時使用。

下面我們來修改getRantsForDay(),使用某種自制形式的緩存:


  
   

這個版本的getRantsForDay()很不好用。這個方法的實際作用是查詢指定日期的帖子,但其中大量代碼都被用於處理緩存了。而且,它還沒有直接處理緩存的一些複雜情況,比如緩存過期、刷新或溢出。

幸運的是,Spring程序有一種更優雅的緩存解決方案。Spring Modules項目(http://springmodules.dev.java.net)通過切面提供了緩存,它把通知應用於Bean方法來透明地對其結果進行緩存,而不是明確地指定要被緩存的方法。

如圖5.13所示,Spring Modules對於緩存的支持涉及到一個代理,它攔截對Spring管理的Bean的一個或多個方法的調用。當一個被代理的方法被調用時,Spring Modules Cache首先查閱一個緩存來判斷這個方法是否已經被使用同樣參數調用過,如果是,它會返回緩存裏的值,實際的方法並不會被調用;否則,實際方法會被調用,其返回值會被保存到緩存裏,以備方法下一次被調用時使用。

  
圖5.13 Spring Module緩存模塊攔截對bean方法
的調用,從緩存獲取數據來實現快速數據訪問,
以此減少對數據庫的實際訪問。
在這一小節裏,我們將使用Spring Modules Cache爲RoadRantz的DAO層添加緩存功能,這樣會讓程序具有更好的性能,讓繁忙的數據庫輕鬆一些。
發佈了80 篇原創文章 · 獲贊 54 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章