<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          PageHelper 使用 ThreadLocal 的線程復(fù)用問(wèn)題,你用對(duì)了嗎?

          共 2058字,需瀏覽 5分鐘

           ·

          2022-02-17 03:30

          點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)??

          前言

          PageHelper 是較為常用的分頁(yè)插件,通過(guò)實(shí)現(xiàn) Mybatis 的 Interceptor 接口完成對(duì) query sql 的動(dòng)態(tài)分頁(yè),其中分頁(yè)參數(shù)由 ThreadLocal 進(jìn)行保存。

          簡(jiǎn)單的 分頁(yè)執(zhí)行過(guò)程:

          1. 設(shè)置 page 參數(shù)
          2. 執(zhí)行 query 方法
          3. Interceptor 接口 中校驗(yàn) ThreadLocal 中是否存在有設(shè)置的 page 參數(shù)
          4. 存在 page 參數(shù),重新生成?count sql?和?page sql,并執(zhí)行查詢。不存在 page 參數(shù),直接返回 查詢結(jié)果
          5. 執(zhí)行?LOCAL_PAGE.remove()清除 page 參數(shù)

          問(wèn)題場(chǎng)景

          觀察上述的執(zhí)行過(guò)程,可以發(fā)現(xiàn),如果在第 1 步和第 2 步 之間發(fā)生異常,那么?LOCAL_PAGE?中當(dāng)前線程對(duì)應(yīng)的 page 參數(shù)并不會(huì) remove。

          在不使用線程池的情況下,當(dāng)前線程在執(zhí)行完畢后會(huì)被銷(xiāo)毀,這時(shí) 當(dāng)前線程 中的 threadLocals 參數(shù) 將會(huì)被情況,也就清空 了?LOCAL_PAGE?中 當(dāng)前線程的 page 參數(shù)。

          但是如果使用了線程池,當(dāng)前線程執(zhí)行完畢,并不會(huì)被銷(xiāo)毀,而是會(huì)將當(dāng)前線程再次存放到池中,標(biāo)記為空閑狀態(tài),以便后續(xù)使用。在后續(xù)使用這個(gè)線程的時(shí)候,由于 線程 的 threadLocals 依舊存在有值,盡管我們?cè)诘?1 步時(shí)未設(shè)置 page 參數(shù),第 3 步 的也能獲取到page參數(shù),從而生成?count sql?和?page sql,從而影響我們的正常查詢。

          SpringBoot 項(xiàng)目中會(huì)使用內(nèi)置的 Tomcat 作為服務(wù)器,而Tomcat會(huì)默認(rèn)使用線程來(lái)處理請(qǐng)求,從而便引發(fā)了上述問(wèn)題。

          解決方案

          因?yàn)門(mén)omcat的線程是用來(lái)處理request請(qǐng)求,那么在請(qǐng)求完成時(shí),清空當(dāng)前線程的threadLocals 屬性值,也就是執(zhí)行?LOCAL_PAGE.remove()?即可。實(shí)現(xiàn)方式:

          • 使用 aop,對(duì)所有 controller 進(jìn)行處理
          • 實(shí)現(xiàn)?HandlerInterceptor?或者?WebRequestInterceptor?對(duì) request 請(qǐng)求的攔截器接口,通過(guò) afterCompletion 方法執(zhí)行?LOCAL_PAGE.remove()?!?推薦,實(shí)現(xiàn)方式簡(jiǎn)單

          這里使用第二種方式,實(shí)現(xiàn)?HandlerInterceptor?接口:

          public?class?PageLocalWebInterceptor?implements?HandlerInterceptor?{
          ????@Override
          ????public?void?afterCompletion(HttpServletRequest?request,?HttpServletResponse?response,?Object?handler,?Exception?ex)?throws?Exception?{

          ????????//?PageHelper.clearPage()?內(nèi)部調(diào)用?LOCAL_PAGE.remove()
          ????????PageHelper.clearPage();

          ????}
          }

          定義配置類(lèi),配置類(lèi)需實(shí)現(xiàn)?WebMvcConfigurer?接口完成對(duì)于WebMvc的相關(guān)配置 ,注冊(cè)?PageLocalWebInterceptor?:

          @Configuration
          public?class?FrameworkAutoConfig?implements?WebMvcConfigurer?{

          ????@Override
          ????public?void?addInterceptors(InterceptorRegistry?registry)?{
          ????????registry.addInterceptor(new?PageLocalWebInterceptor());
          ????}
          }

          來(lái)源:blog.csdn.net/qq_38245668/article/

          details/105984171


          1.?為什么用etcd而不用Zookeeper?

          2.?時(shí)隔三年,Elastic 8 正式發(fā)布 !

          3.?能解決 80% 故障的排查思路 !

          4.?怎么寫(xiě)設(shè)計(jì)文檔?

          最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊(cè),覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù)?Java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

          PS:因公眾號(hào)平臺(tái)更改了推送規(guī)則,如果不想錯(cuò)過(guò)內(nèi)容,記得讀完點(diǎn)一下在看,加個(gè)星標(biāo),這樣每次新文章推送才會(huì)第一時(shí)間出現(xiàn)在你的訂閱列表里。

          點(diǎn)“在看”支持小哈呀,謝謝啦??

          瀏覽 39
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  三级经典欧美大战高潮 | 中文字幕无码A片 | 91av在线免费观看 | 娇精视频 | 男女免费亚洲 |