最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis驗(yàn)證多級(jí)緩存及 Cache Aside 模式的應(yīng)用小結(jié)

 更新時(shí)間:2024年12月05日 11:20:00   作者:Ch.yang  
本文介紹了MyBatis的多級(jí)緩存機(jī)制,包括本地緩存和全局緩存,并通過Spock測(cè)試框架驗(yàn)證了多級(jí)緩存的實(shí)現(xiàn),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

前言

MyBatis 官方文檔 中文版本沒有翻譯cache的部分,網(wǎng)上資料比較雜。
這里使用 Spock 測(cè)試框架驗(yàn)證下多級(jí)緩存,并探索 Mybatis 的 CacheAside 模式。注意:

  • 本文用 本地緩存 表示一級(jí)緩存,全局緩存 表示二級(jí)緩存
  • 用例倉庫

1. 多級(jí)緩存的概念

多級(jí)緩存可以聯(lián)系CPU的結(jié)構(gòu),離核心約近的一致性越高。

1.1 CPU 多級(jí)緩存

1.2 MyBatis 多級(jí)緩存

本地緩存默認(rèn)開啟,全局緩存需要使用 <cache/> 開啟

By default, just local session caching is enabled that is used solely to cache data for the duration of a session. To enable a global second level of caching you simply need to add one line to your SQL Mapping file:

<mapper namespace="com.james.mapper.FileCacheMapper">
    <cache/> <!-- 聲明該標(biāo)簽,全局緩存開啟 -->
    <select id="select" resultType="java.lang.String">
        SELECT file_name FROM file
    </select>
</mapper>

2. MyBatis 本地緩存

用 Spring 注入的 mapper,調(diào)用一次select方法就會(huì)產(chǎn)生一個(gè) sqlSession,沒有利用到本地緩存。

    def "未使用事務(wù),第二次查詢,不命中本地緩存"() {
        given:
        def list1 = mapper.select()
        def list2 = mapper.select()
        expect:
        list1 !== list2
    }

用事務(wù)包裹后,兩次 select 共用一個(gè) sqlSession,緩存命中

 	def "使用事務(wù),命中緩存"() {
        given:
        def list1 = []
        def list2 = []
        when:
        transaction.execute {
            list1 = mapper.select()
            list2 = mapper.select()
        }
        then:
        // 同一個(gè)事務(wù)使用同一個(gè)SqlSession,若引用相同則認(rèn)為命中緩存
        list1 === list2
    }

note: groovy 中 list1 === list2 表示引用相同,list1 == list2 表示兩個(gè)列表的內(nèi)容相同

3. MyBatis 全局緩存

上文說到,沒有事務(wù)保護(hù)的 select方法調(diào)用無法公用一個(gè) sqlSession,所以利用不了本地緩存。
全局緩存的范圍更大,只要是同一個(gè)mapper的調(diào)用,都會(huì)被緩存。

    def "全局緩存默認(rèn)關(guān)閉,需要在xml文件中使用 <cache/> 標(biāo)簽啟用"() {
        given:
        def list1  = fileCacheMapper.select()
        def list2  = fileCacheMapper.select()
        expect:
        // 由于 SerializedCache.java:64 使用的是由byte[]序列化方式存儲(chǔ)元素,所以實(shí)例的地址必然不同
        list1 !== list2
        list1 == list2
    }

3.1 MyBatis 全局緩存過期算法

值得關(guān)注的是 SOFT 和 WEAK 的類型,對(duì)應(yīng)Java中軟引用和弱引用。
軟引用是在內(nèi)存不足時(shí)GC可以回收,弱引用是下次GC即可回收(比軟引用)積極。

3.2 CacheAside 模式

以下是 Mybatis 默認(rèn)的全局緩存失效模式,也就是 Cache Aside 模式的應(yīng)用。

  • 查詢的時(shí)候,如果沒有緩存,則寫入。
  • 任何數(shù)據(jù)操作,使緩存失效。
<select ... flushCache="false" useCache="true"/>
<insert ... flushCache="true"/>
<update ... flushCache="true"/>
<delete ... flushCache="true"/>

后記

Cache Aside 并不能保證強(qiáng)一致性,不然也就不會(huì)有 Paxos 這種復(fù)雜的共識(shí)算法了。 —— 《鳳凰架構(gòu)》

MyBatis 提供了緩存切口, 采用 Redis 會(huì)引入什么問題?

  • 多實(shí)例之間緩存重復(fù)的失效問題,查詢時(shí)競(jìng)爭(zhēng)寫緩存的問題。
  • ORM框架與中間件耦合,違反單一職責(zé)。

萬一遇到需強(qiáng)一致場(chǎng)景,如何增強(qiáng)?

兩個(gè)查詢請(qǐng)求同時(shí)到來,此時(shí)緩存為空,需要將MySql數(shù)據(jù)寫入緩存。此時(shí)會(huì)出現(xiàn)競(jìng)爭(zhēng)寫緩存的情況。用寫鎖來保證緩存內(nèi)的數(shù)據(jù)跟數(shù)據(jù)庫保持一致。

public void query() {
	if (cache 命中) {
		retrun cache
	} 
	獲取緩存寫鎖
	if (獲取鎖失敗) {
		return 查數(shù)據(jù)庫
	} 
	查數(shù)據(jù)庫
	寫緩存
	釋放緩存寫鎖
}

到此這篇關(guān)于MyBatis驗(yàn)證多級(jí)緩存及 Cache Aside 模式的應(yīng)用小結(jié)的文章就介紹到這了,更多相關(guān)MyBatis驗(yàn)證多級(jí)緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring 靜態(tài)變量/構(gòu)造函數(shù)注入失敗的解決方案

    Spring 靜態(tài)變量/構(gòu)造函數(shù)注入失敗的解決方案

    我們經(jīng)常會(huì)遇到一下問題:Spring對(duì)靜態(tài)變量的注入為空、在構(gòu)造函數(shù)中使用Spring容器中的Bean對(duì)象,得到的結(jié)果為空。不要擔(dān)心,本文將為大家介紹如何解決這些問題,跟隨小編來看看吧
    2021-11-11
  • RocketMQ 5.x + Spring Boot 發(fā)送消息失敗全解析

    RocketMQ 5.x + Spring Boot 發(fā)送消息失敗全解

    本文給大家介紹RocketMQ 5.x + Spring Boot 發(fā)送消息失敗全解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2026-02-02
  • java模擬TCP通信實(shí)現(xiàn)客戶端上傳文件到服務(wù)器端

    java模擬TCP通信實(shí)現(xiàn)客戶端上傳文件到服務(wù)器端

    這篇文章主要為大家詳細(xì)介紹了java模擬TCP通信實(shí)現(xiàn)客戶端上傳文件到服務(wù)器端,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Java中操作Word修訂功能的示例詳解

    Java中操作Word修訂功能的示例詳解

    Word的修訂功能是一種在文檔中進(jìn)行編輯和審閱的功能,它允許多個(gè)用戶對(duì)同一文檔進(jìn)行修改并跟蹤這些修改,以便進(jìn)行審查和接受或拒絕修改,下面我們就來學(xué)習(xí)一下Java中操作Word修訂功能的方法,需要的可以參考下
    2023-12-12
  • SpringBoot或SpringAI對(duì)接DeepSeek大模型的詳細(xì)步驟

    SpringBoot或SpringAI對(duì)接DeepSeek大模型的詳細(xì)步驟

    這篇文章主要介紹了DeepSeek智能助手的使用方法和步驟,包括引入庫、配置環(huán)境變量和配置,文章詳細(xì)描述了流式請(qǐng)求和非流式請(qǐng)求的實(shí)現(xiàn)方式,需要的朋友可以參考下
    2025-02-02
  • Spring中@Primary注解的作用詳解

    Spring中@Primary注解的作用詳解

    這篇文章主要介紹了Spring中@Primary注解的作用詳解,@Primary 注解是Spring框架中的一個(gè)注解,用于標(biāo)識(shí)一個(gè)Bean作為默認(rèn)的實(shí)現(xiàn)類,當(dāng)存在多個(gè)實(shí)現(xiàn)類時(shí),通過使用@Primary注解,可以指定其中一個(gè)作為默認(rèn)的實(shí)現(xiàn)類,以便在注入時(shí)自動(dòng)選擇該實(shí)現(xiàn)類,需要的朋友可以參考下
    2023-10-10
  • Java利用JavaCPP調(diào)用算法示例

    Java利用JavaCPP調(diào)用算法示例

    本文主要介紹了Java利用JavaCPP調(diào)用算法示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 由@NotNull注解引出的關(guān)于Java空指針的控制

    由@NotNull注解引出的關(guān)于Java空指針的控制

    這是一些很容易學(xué)會(huì)的簡(jiǎn)單技術(shù),但是對(duì)于代碼質(zhì)量和健壯性來說確實(shí)很重要。以我的經(jīng)驗(yàn),僅是第一個(gè)小技巧就已經(jīng)對(duì)改進(jìn)代碼質(zhì)量具有很大的作用了
    2016-09-09
  • 解決java 分割字符串成數(shù)組時(shí),小圓點(diǎn)不能直接進(jìn)行分割的問題

    解決java 分割字符串成數(shù)組時(shí),小圓點(diǎn)不能直接進(jìn)行分割的問題

    這篇文章主要介紹了解決java 分割字符串成數(shù)組時(shí),小圓點(diǎn)不能直接進(jìn)行分割的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • spring boot下mybatis配置雙數(shù)據(jù)源的實(shí)例

    spring boot下mybatis配置雙數(shù)據(jù)源的實(shí)例

    這篇文章主要介紹了spring boot下mybatis配置雙數(shù)據(jù)源的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評(píng)論

寻乌县| 陆河县| 茌平县| 东方市| 静宁县| 扶风县| 梓潼县| 杭锦旗| 嘉禾县| 西安市| 兴城市| 子洲县| 吴堡县| 岳西县| 曲水县| 宝丰县| 白玉县| 九江市| 通渭县| 塔河县| 金华市| 永吉县| 安平县| 大新县| 遂溪县| 武穴市| 安溪县| 科技| 金塔县| 青川县| 丰宁| 旺苍县| 南投县| 汶川县| 小金县| 阿拉善左旗| 岚皋县| 休宁县| 吕梁市| 拜泉县| 罗甸县|