Mybatis一級緩存和二級緩存 Redis緩存

一級緩存

  • Mybatis的一級緩存存放在SqlSession的生命週期,在同一個SqlSession中查詢時,Mybatis會把執行的方法和參數經過算法生成緩存的鍵值,將鍵值和查詢結果存入一個Map對象中。
  • 若是同一個SqlSession中執行的方法和參數徹底一致,那麼經過算法會生成相同的鍵值,當Map緩存對象中已經存在改鍵值時,則會返回緩存中的對象。(一個SqlSession連續兩次查詢 獲得的是同一個java對象)
  • 任何的insert update delete操做都會清空一級緩存(增刪改任何記錄都會清空當前SqlSession的緩存)。

Spring整合Mybatis的時候一級緩存的問題:java

  在未開啓事物的狀況之下,每次查詢,spring都會關閉舊的sqlSession而建立新的sqlSession,所以此時的一級緩存是沒有啓做用的redis

  在開啓事物的狀況之下,spring使用threadLocal獲取當前資源綁定同一個sqlSession,所以此時一級緩存是有效的算法

Spring結合Mybatis一級緩存失效的問題spring

二級緩存

Mybatis二級緩存能夠理解爲存在SqlSessionFactory的生命週期sql

開啓二級緩存:數據庫

1.在mybatis-config.xml添加以下代碼緩存

<settings>
        <setting name="cacheEnable" value="true"></setting>
    </settings>

2.在對應的XXXMapper.xml的namespace下添加<cache/>元素mybatis

二級緩存特色:併發

SqlSession1調用getMapper獲取對象user1app

SqlSession1調用getMapper獲取對象user2

user1和user2是同一個實例(原理同一級緩存)

若是二級配置可讀寫的緩存 <cache readOnly="false"/>,不一樣SqlSession之間經過序列化和反序列化來保證經過緩存獲取數據。

SqlSession2調用getMapper獲取對象user1_

SqlSession2調用getMapper獲取對象user2_

user1_和user2_就是反序列化獲得的結果 是不一樣的實例

Redis緩存一致性

Mybatis默認提供的緩存是基於Map實現的內存緩存,已經能夠基本知足應用。但當須要緩存大量數據的時候可使用Redis緩存數據庫來保存Mybatis的二級緩存數據。

但MySQL和Redis是兩個事物,很差作強一致性。

簡單點:能夠延時雙刪+過時時間保證最終一致性。

雙刪的緣由是防止併發狀況下 update_db的過程當中 其餘事物發現redis緩存是空 從新賦予了Redis的值 此時若是賦值 是錯誤的數據

第二次延時刪除的緣由是要考慮MySQL數據庫主從同步的耗時(若是當即刪除 有別的線程從MySQL的從庫查到的數據放到Redis中 此時的從庫多是沒同步的錯誤數據)

rm_redis update_db sleep xxx ms rm_redis
相關文章
相關標籤/搜索