mybatis緩存的設計

繼續用提問的方式來看Mybatis的緩存設計。

1、Mybatis如何開啓緩存

Mybatis對查詢結果進行緩存,所以緩存的對象爲具體的Statement

通過在Statement上是否使用緩存來啓用。

<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap"  fetchSize="5" statementType="PREPARED" useCache="true" >
useCache默認值爲true

2、誰持有緩存?

 Mybatis中有兩個對象持有緩存。

CachingExecutor以及BaseExecutor

   

CachingExecutor和SimpleExecutor的關係是持有的關係
public class CachingExecutor implements Executor {

  private final Executor delegate;
  private final TransactionalCacheManager tcm = new TransactionalCacheManager();

 

 

3、緩存何時開啓?

  當開啓Mapper級別的緩存時,緩存被開啓

  緩存是一直開啓的

4、緩存何時被命中?

 

  5、緩存清空的時機

  ①數據庫發生變更(update,insert,delete),即使事物沒有提交,緩存失效

  ②對於相同命名空間Mapper的緩存,多個線程,併發使用相同Mapper的不同語句,任意一個執行事物提交,可導致緩存失效

  實際效果:

  緩存 會和Mysql的rr隔離級別一致,不會導致幻讀(read uncommited)

  緩存 在不使用緩存的時候,有效

  驗證緩存

          

  使用代碼驗證:

  兩次查詢,只訪問了數據庫1次.第二次不再請求數據庫

    

  一次查詢,一次更新(不提交),一次查詢.緩存失效,出發了兩次數據庫查詢。

      

  緩存的驗證

  不配置緩存時,驗證不同的sqlSesiion緩存是否通用

  觸發2次數據庫訪問

    

   配置緩存參數

<settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
<cache/>

   

  結果出乎意料,緩存竟然沒有命中。分析下原因:

   

  即使打開了緩存,首先也是保存在事物級別的緩存裏,TransactionalCache裏.

  只有當實物提交時,纔會真正將緩存轉移到delegate中(delegate是真正的Mapper之間公用的緩存)

  調整代碼,後緩存生效。

  

  讓人不理解的,出於什麼目的,要commit後,再共享?

  如果在某一秒,有10個併發共同訪問數據庫。那他們會同時產生10個連接,並不會命中。  

6、Mybatis緩存設計的目的

  簡單,不配置也可以使用。用與在一個sqlSession中多次使用相同條件多次查詢。

7、Mybatis緩存設計的目的

  增強版,也支持事物級別的緩存,同時支持不同sqlSession之間的共享。擴大可緩存的可用性。

 

原文出處:https://www.cnblogs.com/marioS/p/10353468.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章