參考博客:html
https://www.cnblogs.com/zhangyu0217----/p/7574704.htmlspring
http://www.javashuo.com/article/p-ajgyutpq-mq.htmlsql
https://blog.csdn.net/chenyao1994/article/details/79233725數據庫
緩存是介於物理數據源與應用程序之間,是對數據庫中的數據複製一份臨時放在內存中的容器,緩存
其做用是爲了減小應用程序對物理數據源訪問的次數,從而提升了應用程序的運行性能。session
Hibernate在進行讀取數據的時候,根據緩存機制在相應的緩存中查詢,若是在緩存中找到了須要的數據(咱們把這稱作「緩存命 中"),mybatis
則就直接把命中的數據做爲結果加以利用,避免了大量發送SQL語句到數據庫查詢的性能損耗。併發
通常咱們在項目整合中 存在數據訪問的性能問題,研究了下緩存在各個階段的應用,以在5個方面進行緩存的設計:性能
1.最底層能夠配置的是MySQL自帶的query cache,測試
2.mybatis的一級緩存,默認狀況下都處於開啓狀態,只能使用自帶的PerpetualCache,沒法配置第三方緩存
3.mybatis的二級緩存,能夠配置開關狀態,默認使用自帶的PerpetualCache,但功能比較弱,可以配置第三方緩存,
4.service層的緩存配置,結合spring,能夠靈活進行選擇
5.hibernate的一級緩存,默認也是開啓狀態,session級別的,能夠自由使用。但這裏注意下hibernate獲取session的 方式。
6.hibernate的二級緩存須要引用 第三方的 插件,並在hibernate配置文件中進行相應的配置。
7.針對實際業務狀況,直接緩存部分html頁面,直接返回給客戶端。
發如今整合的項目測試中被spring整合的mybatis和hibernate的一級緩存都失效了。
首先1.mybatis和hibernate的一級緩存生效的範圍是sqlsession,是爲了在sqlsession沒有關閉時,業務須要重複查詢相同數據使用的。一旦sqlsession關閉,則由這個sqlsession緩存的數據將會被清空。
一級緩存
就是Session級別的緩存。一個Session作了一個查詢操做,它會把這個操做的結果放在一級緩存中。
若是短期內這個session(必定要同一個session)又作了同一個操做,那麼hibernate直接從一級緩存中拿,而不會再去連數據庫,取數據。
它是內置的事務範圍的緩存,不能被卸載。
二級緩存:
就是SessionFactory級別的緩存。顧名思義,就是查詢的時候會把查詢結果緩存到二級緩存中。
若是同一個sessionFactory建立的某個session執行了相同的操做,hibernate就會從二級緩存中拿結果,而不會再去鏈接數據庫。
這是可選的插件式的緩存,在默認狀況下,SessionFactory不會啓用這個插件。
能夠在每一個類或每一個集合的粒度上配置。緩存適配器用於把具體的緩存實現軟件與Hibernate集成。
嚴格意義上說,SessionFactory緩存分爲兩類:內置緩存和外置緩存。咱們一般意義上說的二級緩存是指外置緩存。
內置緩存與session級別緩存實現方式類似。前者是SessionFactory對象的一些集合屬性包含的數據,後者是指Session的一些集合屬性包含的數據
SessionFactory的內置緩存中存放了映射元數據和預約義SQL語句。
映射元數據是映射文件中數據的拷貝;
而預約義SQL語句是在Hibernate初始化階段根據映射元數據推導出來。
SessionFactory的內置緩存是隻讀的,應用程序不能修改緩存中的映射元數據和預約義SQL語句,所以SessionFactory不須要進行內置緩存與映射文件的同步。
Hibernate的這兩級緩存都位於持久化層,存放的都是數據庫數據的拷貝。
緩存的兩個特性:
緩存的範圍
緩存的併發訪問策略
一、緩存的範圍
決定了緩存的生命週期以及能夠被誰訪問。緩存的範圍分爲三類。
事務範圍
進程範圍
集羣範圍
注:
對大多數應用來講,應該慎重地考慮是否須要使用集羣範圍的緩存,由於訪問的速度不必定會比直接訪問數據庫數據的速度快多少。
事務範圍的緩存是持久化層的第一級緩存,一般它是必需的;進程範圍或集羣範圍的緩存是持久化層的第二級緩存,一般是可選的。
二、緩存的併發訪問策略
當多個併發的事務同時訪問持久化層的緩存的相同數據時,會引發併發問題,必須採用必要的事務隔離措施。
在進程範圍或集羣範圍的緩存,即第二級緩存,會出現併發問題。
所以能夠設定如下四種類型的併發訪問策略,每一種策略對應一種事務隔離級別。
事務型併發訪問策略是事務隔離級別最高,只讀型的隔離級別最低。事務隔離級別越高,併發性能就越低。
A 事務型:僅僅在受管理環境中適用。它提供了Repeatable Read事務隔離級別。
對於常常被讀但不多修改的數據,能夠採用這種隔離類型,由於它能夠防止髒讀和不可重複讀這類的併發問題。
B 讀寫型:提供了Read Committed事務隔離級別。僅僅在非集羣的環境中適用。
對於常常被讀但不多修改的數據,能夠採用這種隔離類型,由於它能夠防止髒讀這類的併發問題。
C 非嚴格讀寫型:不保證緩存與數據庫中數據的一致性。
若是存在兩個事務同時訪問緩存中相同數據的可能,必須爲該數據配置一個很短的數據過時時間,從而儘可能避免髒讀。
對於極少被修改,而且容許偶爾髒讀的數據,能夠採用這種併發訪問策略。
D 只讀型:對於歷來不會修改的數據,如參考數據,可使用這種併發訪問策略。
什麼樣的數據適合存放到第二級緩存中?
一、不多被修改的數據
二、不是很重要的數據,容許出現偶爾併發的數據
三、不會被併發訪問的數據
四、參考數據
不適合存放到第二級緩存的數據?
一、常常被修改的數據
二、財務數據,絕對不容許出現併發
三、與其餘應用共享的數據。
Hibernate的二級緩存策略的通常過程以下:
1) 條件查詢的時候,老是發出一條select * from table_name where …. (選擇全部字段)這樣的SQL語句查詢數據庫,一次得到全部的數據對象。
2) 把得到的全部數據對象根據ID放入到第二級緩存中。
3) 當Hibernate根據ID訪問數據對象的時候,首先從Session一級緩存中查;查不到,若是配置了二級緩存,那麼從二級緩存中查;查不到,再查詢數據庫,把結果按照ID放入到緩存。
4) 刪除、更新、增長數據的時候,同時更新緩存。
注:
Hibernate的二級緩存策略,是針對於ID查詢的緩存策略,對於條件查詢則毫無做用。爲此,Hibernate提供了針對條件查詢的Query緩存。
Query緩存策略的過程以下:
1) Hibernate首先根據這些信息組成一個Query Key,Query Key包括條件查詢的請求通常信息:SQL, SQL須要的參數,記錄範圍(起始位置rowStart,最大記錄個數maxRows),等。
2) Hibernate根據這個Query Key到Query緩存中查找對應的結果列表。若是存在,那麼返回這個結果列表;若是不存在,查詢數據庫,獲取結果列表,把整個結果列表根據Query Key放入到Query緩存中。
3) Query Key中的SQL涉及到一些表名,若是這些表的任何數據發生修改、刪除、增長等操做,這些相關的Query Key都要從緩存中清空。
圖: (太忙, 後期補上吧)