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

PageHelper引發(fā)的幽靈數(shù)據(jù)問題解析

 更新時(shí)間:2023年04月19日 14:45:13   作者:java旭陽(yáng)  
這篇文章主要為大家介紹了PageHelper引發(fā)的幽靈數(shù)據(jù)問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

最近測(cè)試反饋一個(gè)問題,某個(gè)查詢?nèi)啃畔⒌慕涌?,有時(shí)候返回全量數(shù)據(jù),符合預(yù)期,但是偶爾又只返回1條數(shù)據(jù),簡(jiǎn)直就是“見鬼”了,究竟是為什么出現(xiàn)這樣的“幽靈數(shù)據(jù)”呢?

大膽猜測(cè)

首先我們看了下這對(duì)代碼的業(yè)務(wù)邏輯,非常的簡(jiǎn)單,總共沒有幾行代碼,也沒有分頁(yè)邏輯,代碼如下:

public  List<SdSubscription> findAll() {
    return sdSubscriptionMapper.selectAll();
}

那么究竟是咋回事呢?講道理不可能出現(xiàn)這種情況的啊,不要慌,我們加點(diǎn)日志,將日志級(jí)別調(diào)整為DEBUG,讓日志飛一段時(shí)間。

public  List<SdSubscription> findAll() {
    log.info("find the sub start .....");
    List<SdSubscription> subs = sdSubscriptionMapper.selectAll();
     log.info("find the sub end .....");
    return subs;
}

果不其然,日志中出現(xiàn)了奇奇怪怪的分頁(yè)參數(shù),如下圖所示:

果然是PageHelper這個(gè)開源框架搞的鬼,我想大家都用過吧,分頁(yè)非常方便,那么究竟為什么別人都沒問題,單單就我會(huì)出現(xiàn)問題呢?

PageHelper工作原理

為了回答上面的疑問,我們先看看PageHelper框架的工作原理吧。

PageHelper 是一個(gè)開源的 MyBatis 分頁(yè)插件,它可以幫助開發(fā)者在查詢數(shù)據(jù)時(shí),快速的實(shí)現(xiàn)分頁(yè)功能。

PageHelper 的工作原理可以簡(jiǎn)單概括為以下幾個(gè)步驟:

  • 在需要進(jìn)行分頁(yè)的查詢方法前,調(diào)用 PageHelper 的靜態(tài)方法 startPage(),設(shè)置當(dāng)前頁(yè)碼和每頁(yè)顯示的記錄數(shù)。它會(huì)將分頁(yè)信息放到線程的ThreadLocal中,那么在線程的任何地方都可以訪問了。
  • 當(dāng)查詢方法執(zhí)行時(shí),PageHelper 會(huì)自動(dòng)攔截查詢語(yǔ)句,如果發(fā)現(xiàn)線程的ThreadLocal中有分頁(yè)信息,那么就會(huì)在其前后添加分頁(yè)語(yǔ)句,例如 MySQL 中的 LIMIT 語(yǔ)句。
  • 查詢結(jié)果將被包裝在 Page 對(duì)象中返回,該對(duì)象包含分頁(yè)信息和查詢結(jié)果列表。
  • 在查詢方法執(zhí)行完畢后,會(huì)在finally中清除線程ThreadLocal中的分頁(yè)信息,避免分頁(yè)設(shè)置對(duì)其他查詢方法的影響。

PageHelper 的實(shí)現(xiàn)原理主要依賴于攔截器技術(shù)和反射機(jī)制,通過攔截查詢語(yǔ)句并動(dòng)態(tài)生成分頁(yè)語(yǔ)句,實(shí)現(xiàn)了簡(jiǎn)單、高效、通用的分頁(yè)功能。具體源碼在下圖的類中,非常容易看懂。

明白了PageHelper的工作原理后,反復(fù)檢查代碼,都沒有調(diào)用過startPagedebug查看ThreadLocal中也沒有分頁(yè)信息啊,懵逼中。那我看看別人寫的添加分頁(yè)參數(shù)的代碼吧,不看不知道,一看嚇一跳。

原來有位“可愛”的同事竟然在查詢后,加了一個(gè)分頁(yè),就是把分頁(yè)信息放到線程的ThreadLocal中。

那大家是不是有疑問,丁是丁,矛是矛,你的線程關(guān)我何事?這就要說到我們的tomcat了。

Tomcat請(qǐng)求流程

其實(shí)這就涉及到我們的tomcat相關(guān)知識(shí)了,我們一個(gè)瀏覽器發(fā)一個(gè)接口請(qǐng)求,經(jīng)過我們的tomcat的,究竟是一個(gè)什么樣的流程呢?

  • 客戶端發(fā)送HTTP請(qǐng)求到Tomcat服務(wù)器。
  • TomcatHTTP連接器(Connector)接收到請(qǐng)求,將連接請(qǐng)求交給線程池Executor處理,解析它,然后將請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)的Web應(yīng)用程序。
  • Tomcat的Web應(yīng)用程序容器(Container)接收到請(qǐng)求,根據(jù)請(qǐng)求的URL找到對(duì)應(yīng)的Servlet。

關(guān)于tomcat中使用線程池提交瀏覽器的連接請(qǐng)求的源碼如下:

從而得知,你的連接請(qǐng)求是從線程池從拿的,而拿到的這個(gè)線程恰好是一個(gè)“臟線程”,在ThreadLocal中放了分頁(yè)信息,導(dǎo)致你這邊出現(xiàn)問題。

總結(jié)

后來追問了同事具體原因,才發(fā)現(xiàn)是粗心導(dǎo)致的。有些bug總是出現(xiàn)的莫名其妙,就像生活一樣。所以關(guān)鍵的是我們?cè)谑褂靡恍╅_源框架的時(shí)候一定要掌握底層實(shí)現(xiàn)的原理、核心的機(jī)制,這樣才能夠在解決一些問題的時(shí)候有據(jù)可循。

以上就是PageHelper引發(fā)的幽靈數(shù)據(jù)問題解析的詳細(xì)內(nèi)容,更多關(guān)于PageHelper幽靈數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Springboot+AOP實(shí)現(xiàn)返回?cái)?shù)據(jù)提示語(yǔ)國(guó)際化的示例代碼

    Springboot+AOP實(shí)現(xiàn)返回?cái)?shù)據(jù)提示語(yǔ)國(guó)際化的示例代碼

    這篇文章主要介紹了Springboot+AOP實(shí)現(xiàn)返回?cái)?shù)據(jù)提示語(yǔ)國(guó)際化的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • IntelliJ IDEA配置java環(huán)境及解決IDEA不能直接運(yùn)行單個(gè)JAVA文件的問題

    IntelliJ IDEA配置java環(huán)境及解決IDEA不能直接運(yùn)行單個(gè)JAVA文件的問題

    這篇文章主要介紹了IntelliJ IDEA配置java環(huán)境及解決IDEA不能直接運(yùn)行單個(gè)JAVA文件的問題,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java進(jìn)階學(xué)習(xí)之如何開啟遠(yuǎn)程調(diào)式

    Java進(jìn)階學(xué)習(xí)之如何開啟遠(yuǎn)程調(diào)式

    Java開發(fā)中的遠(yuǎn)程調(diào)試是一項(xiàng)至關(guān)重要的技能,特別是在處理生產(chǎn)環(huán)境的問題或者協(xié)作開發(fā)時(shí),這篇文章主要介紹了Java進(jìn)階學(xué)習(xí)之如何開啟遠(yuǎn)程調(diào)式的相關(guān)資料,需要的朋友可以參考下
    2025-03-03
  • 為何HashSet中使用PRESENT而不是null作為value

    為何HashSet中使用PRESENT而不是null作為value

    這篇文章主要介紹了為何HashSet中使用PRESENT而不是null作為value,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • SpringBoot3利用AOP實(shí)現(xiàn)IP黑名單功能

    SpringBoot3利用AOP實(shí)現(xiàn)IP黑名單功能

    在Web應(yīng)用開發(fā)中,控制對(duì)特定IP地址的訪問權(quán)限是一個(gè)常見的需求,通過實(shí)現(xiàn)IP黑白名單功能,我們可以允許某些IP地址訪問應(yīng)用,同時(shí)拒絕其他IP地址的訪問,本文將詳細(xì)介紹SpringBoot3利用AOP實(shí)現(xiàn)IP黑名單功能,并附上相應(yīng)的代碼片段,需要的朋友可以參考下
    2024-09-09
  • Java contains用法示例

    Java contains用法示例

    這篇文章主要介紹了Java contains的用法示例,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-11-11
  • 遠(yuǎn)程調(diào)用@FeignClient注解屬性使用詳解

    遠(yuǎn)程調(diào)用@FeignClient注解屬性使用詳解

    這篇文章主要為大家介紹了遠(yuǎn)程調(diào)用@FeignClient注解屬性使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 關(guān)于Spring項(xiàng)目對(duì)JDBC的支持與基本使用詳解

    關(guān)于Spring項(xiàng)目對(duì)JDBC的支持與基本使用詳解

    這段時(shí)間一直在觀看Spring框架,所以下面這篇文章主要給大家介紹了關(guān)于Spring項(xiàng)目對(duì)JDBC的支持與基本使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • 反編譯jar實(shí)現(xiàn)的三種方式

    反編譯jar實(shí)現(xiàn)的三種方式

    本文主要介紹了反編譯jar實(shí)現(xiàn)的三種方式,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Spring Boot整合SSE實(shí)時(shí)通信的問題小結(jié)

    Spring Boot整合SSE實(shí)時(shí)通信的問題小結(jié)

    本文介紹了服務(wù)器發(fā)送事件(Server-Sent Events,SSE)技術(shù),其主要特點(diǎn)包括單向數(shù)據(jù)流、自動(dòng)重連、自定義事件類型等,SSE適用于實(shí)時(shí)更新場(chǎng)景,如新聞推送、評(píng)論系統(tǒng)等,感興趣的朋友跟隨小編一起看看吧
    2025-01-01

最新評(píng)論

图们市| 贡山| 潞城市| 三穗县| 晴隆县| 玉环县| 东平县| 许昌县| 进贤县| 五常市| 申扎县| 古蔺县| 云霄县| 莎车县| 碌曲县| 雅安市| 龙海市| 南和县| 措美县| 开封市| 华亭县| 筠连县| 灵山县| 三都| 曲靖市| 朝阳市| 苍溪县| 化德县| 新田县| 宝坻区| 洪湖市| 乃东县| 吴忠市| 怀来县| 丰城市| 应城市| 北碚区| 桓仁| 苍溪县| 榆中县| 屯留县|