欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

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

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

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

1.1 CPU 多級(jí)緩存

1.2 MyBatis 多級(jí)緩存

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

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)簽,全局緩存開(kāi)啟 -->
    <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,沒(méi)有利用到本地緩存。

    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 全局緩存

上文說(shuō)到,沒(méi)有事務(wù)保護(hù)的 select方法調(diào)用無(wú)法公用一個(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ò)期算法

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

3.2 CacheAside 模式

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

  • 查詢的時(shí)候,如果沒(méi)有緩存,則寫入。
  • 任何數(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ì)引入什么問(wèn)題?

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

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

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

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

到此這篇關(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)文章

  • Java使用Zxing二維碼生成的簡(jiǎn)單示例

    Java使用Zxing二維碼生成的簡(jiǎn)單示例

    ZXing是一個(gè)開(kāi)源的,用Java實(shí)現(xiàn)的多種格式的1D/2D條碼圖像處理庫(kù),下面這篇文章主要給大家介紹了關(guān)于Java使用Zxing二維碼生成的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • jmeter的時(shí)間戳函數(shù)使用

    jmeter的時(shí)間戳函數(shù)使用

    在使用jmeter做接口測(cè)試的時(shí)候,經(jīng)常會(huì)要用到日期這種函數(shù),本文主要介紹了jmeter的時(shí)間戳函數(shù)使用,感興趣的可以了解一下
    2021-11-11
  • Java Calendar類常用示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java Calendar類常用示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    從JDK1.1版本開(kāi)始,在處理日期和時(shí)間時(shí),系統(tǒng)推薦使用Calendar類進(jìn)行實(shí)現(xiàn)。接下來(lái)通過(guò)實(shí)例代碼給大家詳細(xì)介紹Java Calendar類相關(guān)知識(shí),需要的朋友參考下吧
    2017-04-04
  • Java并發(fā)容器相關(guān)知識(shí)總結(jié)

    Java并發(fā)容器相關(guān)知識(shí)總結(jié)

    今天給大家?guī)?lái)的文章是Java并發(fā)容器的相關(guān)知識(shí),文中有非常詳細(xì)的介紹,對(duì)正在學(xué)習(xí)Java并發(fā)容器的小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • Java中JSONObject和Map<String,?Object>的轉(zhuǎn)換方法

    Java中JSONObject和Map<String,?Object>的轉(zhuǎn)換方法

    平時(shí)對(duì)接口時(shí),經(jīng)常遇到j(luò)son字符串和map對(duì)象之間的交互,這篇文章主要給大家介紹了關(guān)于Java中JSONObject和Map<String,?Object>的轉(zhuǎn)換方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • 使用Java反射獲取方法的全路徑名稱的步驟

    使用Java反射獲取方法的全路徑名稱的步驟

    Java反射是一個(gè)強(qiáng)大的特性,它允許程序在運(yùn)行時(shí)查詢和修改類的行為,反射可以用于實(shí)現(xiàn)很多高級(jí)功能,比如動(dòng)態(tài)代理、依賴注入等,本文將介紹如何使用Java反射來(lái)實(shí)現(xiàn)這一功能,需要的朋友可以參考下
    2024-07-07
  • Spring實(shí)現(xiàn)Logback日志模板設(shè)置動(dòng)態(tài)參數(shù)功能

    Spring實(shí)現(xiàn)Logback日志模板設(shè)置動(dòng)態(tài)參數(shù)功能

    本文介紹如何在Spring應(yīng)用中實(shí)現(xiàn)Logback日志模板的動(dòng)態(tài)參數(shù)設(shè)置,通過(guò)設(shè)計(jì)traceId鏈路標(biāo)識(shí),將其動(dòng)態(tài)添加到日志輸出中,從而實(shí)現(xiàn)簡(jiǎn)易的鏈路追蹤功能,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Springmvc conver實(shí)現(xiàn)原理及用法解析

    Springmvc conver實(shí)現(xiàn)原理及用法解析

    這篇文章主要介紹了Springmvc conver實(shí)現(xiàn)原理及用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • java判斷字符串中是否包含中文并過(guò)濾中文

    java判斷字符串中是否包含中文并過(guò)濾中文

    這篇文章主要為大家詳細(xì)介紹了java判斷字符串中是否包含中文,并過(guò)濾掉中文,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • hadoop是什么語(yǔ)言

    hadoop是什么語(yǔ)言

    Hadoop是一個(gè)由Apache基金會(huì)所開(kāi)發(fā)的分布式系統(tǒng)基礎(chǔ)架構(gòu)。 用戶可以在不了解分布式底層細(xì)節(jié)的情況下,開(kāi)發(fā)分布式程序。充分利用集群的威力進(jìn)行高速運(yùn)算和存儲(chǔ)
    2017-09-09

最新評(píng)論