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

SpringBoot大事務(wù)問題的常用優(yōu)化方案

 更新時(shí)間:2024年04月26日 11:29:55   作者:牽著貓散步的鼠鼠  
大事務(wù)是指運(yùn)行時(shí)間比較長(zhǎng),操作的數(shù)據(jù)比較多的事務(wù)123,大事務(wù)的產(chǎn)生原因包括操作的數(shù)據(jù)比較多、大量的鎖競(jìng)爭(zhēng)、事務(wù)中有其他非數(shù)據(jù)庫的耗時(shí)操作等,本文給大家總結(jié)了SpringBoot大事務(wù)問題的常用優(yōu)化方案,需要的朋友可以參考下

1.前言

在分享解決辦法之前,先看看系統(tǒng)中如果出現(xiàn)大事務(wù)可能會(huì)引發(fā)哪些問題

從上圖可以看出,如果系統(tǒng)中出現(xiàn)大事務(wù)的問題,那么情況不容樂觀。

因此,在實(shí)際項(xiàng)目開發(fā)中,我們應(yīng)該盡量避免大事務(wù)的情況。

2.什么是大事務(wù)

大事務(wù)是指運(yùn)行時(shí)間比較長(zhǎng),操作的數(shù)據(jù)比較多的事務(wù)123。例如,執(zhí)行超過5秒、10秒、1分鐘等。大事務(wù)的產(chǎn)生原因包括操作的數(shù)據(jù)比較多、大量的鎖競(jìng)爭(zhēng)、事務(wù)中有其他非數(shù)據(jù)庫的耗時(shí)操作等。

3.解決辦法

3.1.少用@Transactional注解

在實(shí)際項(xiàng)目中,開啟事務(wù)功能是非常常見的做法。在業(yè)務(wù)方法上加上@Transactional注解,可以方便地開啟事務(wù)功能,這種做法被稱為聲明式事務(wù)。

@Transactional(rollbackFor=Exception.class)
   public void save(User user) {
         doSameThing...
   }

為什么說要少用@Transactional注解?

  • 我們知道@Transactional注解是通過spring的aop起作用的,但是如果使用不當(dāng),事務(wù)功能可能會(huì)失效。
  • @Transactional注解一般加在某個(gè)業(yè)務(wù)方法上,會(huì)導(dǎo)致整個(gè)業(yè)務(wù)方法都在同一個(gè)事務(wù)中,粒度太粗,不好控制事務(wù)范圍,是出現(xiàn)大事務(wù)問題的最常見的原因。

那可以使用編程式事務(wù),在spring項(xiàng)目中使用TransactionTemplate類的對(duì)象,手動(dòng)執(zhí)行事務(wù)。

 
   @Autowired
   private TransactionTemplate transactionTemplate;
   
   ...
   
   public void save(final User user) {
         transactionTemplate.execute((status) => {
            doSameThing...
            return true;
         })
   }

3.2.將查詢(select)方法放到事務(wù)外

查詢(select)方法一般情況下是不需要事務(wù)的,所以應(yīng)該放到事務(wù)外!

@Transactional(rollbackFor=Exception.class)
   public void save(User user) {
         query1();
         query2();
         add1();
         update2();
   }

可以將query1和query2兩個(gè)查詢方法放在事務(wù)外執(zhí)行,將真正需要事務(wù)執(zhí)行的代碼才放到事務(wù)中,比如:add1和update2方法,這樣就能有效的減少事務(wù)的粒度。

可以用這個(gè)TransactionTemplate來解決!

 
   @Autowired
   private TransactionTemplate transactionTemplate;
   
   ...
   
   public void save(final User user) {
         query1();
         query2();
         transactionTemplate.execute((status) => {
            add1();
            update2();
            return Boolean.TRUE;
         })
   }

但是如果你實(shí)在還是想用@Transactional注解,該怎么拆分呢?

public void save(User user) {
         query1();
         query2();
         doSave();
    }
   
    @Transactional(rollbackFor=Exception.class)
    public void doSave(User user) {
       add1();
       update2();
    }

在一個(gè)Service內(nèi)部,事務(wù)方法之間的嵌套調(diào)用,普通方法和事務(wù)方法之間的嵌套調(diào)用,都不會(huì)開啟新的事務(wù)。是因?yàn)槁暶魇绞聞?wù)來實(shí)現(xiàn)事務(wù)控制,當(dāng)我們通過this調(diào)用普通方法時(shí),是通過原始對(duì)象而不是代理對(duì)象調(diào)用的方法,導(dǎo)致事務(wù)

不過這邊事務(wù)是失效的,因?yàn)橹苯臃椒ㄕ{(diào)用使用的還是原始對(duì)象,所以事務(wù)不會(huì)生效。

那該怎么解決呢?

1.新加Service方法

這個(gè)方法非常簡(jiǎn)單,只需要新加Service方法,把@Transactional注解加到新Service方法上,把需要事務(wù)執(zhí)行的代碼移到新方法中。具體代碼如下:

@Servcie
  publicclass ServiceA {
     @Autowired
     prvate ServiceB serviceB;
  
     public void save(User user) {
           query1();
           query2();
           serviceB.doSave(user);
     }
   }
   
   @Servcie
   publicclass ServiceB {
   
      @Transactional(rollbackFor=Exception.class)
      public void doSave(User user) {
         add1();
         update2();
      }
   
   }

2.在該Service類中注入自己

在該Service類中注入自己也是一種選擇,如下:

@Servcie
  publicclass ServiceA {
     @Autowired
     prvate ServiceA serviceA;
  
     public void save(User user) {
           query1();
           query2();
           serviceA.doSave(user);
     }
     
     @Transactional(rollbackFor=Exception.class)
     public void doSave(User user) {
         add1();
         update2();
      }
   }

spring ioc內(nèi)部的三級(jí)緩存保證了它,不會(huì)出現(xiàn)循環(huán)依賴問題。

3.在該Service類中使用AopContext.currentProxy()獲取代理對(duì)象

通過在該Service類中使用AOPProxy獲取代理對(duì)象,實(shí)現(xiàn)相同的功能。如下:

@Servcie
  publicclass ServiceA {
  
     public void save(User user) {
           query1();
           query2();
           ((ServiceA)AopContext.currentProxy()).doSave(user);
     }
     
     @Transactional(rollbackFor=Exception.class)
     public void doSave(User user) {
         add1();
         update2();
      }
   }

3.3.事務(wù)中避免遠(yuǎn)程調(diào)用

網(wǎng)絡(luò)不穩(wěn)定,遠(yuǎn)程調(diào)其他系統(tǒng)響應(yīng)時(shí)間可能比較長(zhǎng),這就是大事務(wù)!

當(dāng)然,發(fā)MQ消息,或者連接redis、mongodb保存數(shù)據(jù)等也屬于遠(yuǎn)程調(diào)用哦!

@Transactional(rollbackFor=Exception.class)
   public void save(User user) {
         callRemoteApi();
         addData1();
   }

遠(yuǎn)程調(diào)用的代碼可能耗時(shí)較長(zhǎng),切記一定要放在事務(wù)之外。

 
   @Autowired
   private TransactionTemplate transactionTemplate;
   
   ...
   
   public void save(final User user) {
         callRemoteApi();
         transactionTemplate.execute((status) => {
            addData1();
            return Boolean.TRUE;
         })
   }

不過這就需要建立:重試+補(bǔ)償機(jī)制,達(dá)到數(shù)據(jù)最終一致性了。

3.4.事務(wù)中避免一次性處理太多數(shù)據(jù)

如果一個(gè)事務(wù)中需要處理的數(shù)據(jù)太多,也會(huì)造成大事務(wù)問題。

你可能會(huì)一次批量更新1000條數(shù)據(jù),這樣會(huì)導(dǎo)致大量數(shù)據(jù)鎖等待,特別在高并發(fā)的系統(tǒng)中問題尤為明顯! 那怎么解決呢?

用分頁處理,1000條數(shù)據(jù),分20頁,一次只處理50條數(shù)據(jù),這樣可以大大減少大事務(wù)的出現(xiàn)。

3.5.非事務(wù)執(zhí)行

在使用事務(wù)之前,我們都應(yīng)該思考一下,是不是所有的數(shù)據(jù)庫操作都需要在事務(wù)中執(zhí)行?

 
   @Autowired
   private TransactionTemplate transactionTemplate;
   
   ...
   
   public void save(final User user) {
         transactionTemplate.execute((status) => {
            addData();
            addLog();
            updateCount();
            return Boolean.TRUE;
         })
   }

上面的例子中,其實(shí)addLog增加操作日志方法 和 updateCount更新統(tǒng)計(jì)數(shù)量方法,是可以不在事務(wù)中執(zhí)行的,因?yàn)椴僮魅罩竞徒y(tǒng)計(jì)數(shù)量這種業(yè)務(wù)允許少量數(shù)據(jù)不一致的情況。

 
   @Autowired
   private TransactionTemplate transactionTemplate;
   
   ...
   
   public void save(final User user) {
         transactionTemplate.execute((status) => {
            addData();           
            return Boolean.TRUE;
         })
         addLog();
         updateCount();
   }

當(dāng)然大事務(wù)中要鑒別出哪些方法可以非事務(wù)執(zhí)行,其實(shí)沒那么容易,需要對(duì)整個(gè)業(yè)務(wù)梳理一遍,才能找出最合理的答案。

3.6.異步處理

我們都知道,方法同步執(zhí)行需要等待方法返回,如果一個(gè)事務(wù)中同步執(zhí)行的方法太多了,勢(shì)必會(huì)造成等待時(shí)間過長(zhǎng),出現(xiàn)大事務(wù)問題。

看看下面這個(gè)列子:

 
   @Autowired
   private TransactionTemplate transactionTemplate;
   
   ...
   
   public void save(final User user) {
         transactionTemplate.execute((status) => {
            order();
            delivery();
            return true;
         })
   }

order方法用于下單,delivery方法用于發(fā)貨,是不是下單后就一定要馬上發(fā)貨呢?

答案是否定的。

這里發(fā)貨功能其實(shí)可以走mq異步處理邏輯。

 
   @Autowired
   private TransactionTemplate transactionTemplate;
   
   ...
   
   public void save(final User user) {
         transactionTemplate.execute((status) => {
            order();
            return Boolean.TRUE;
         })
         sendMq();
   }

4.總結(jié)

以上就是SpringBoot大事務(wù)問題的常用優(yōu)化方案的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot大事務(wù)優(yōu)化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java讀取無限量文件的思路和完整代碼

    Java讀取無限量文件的思路和完整代碼

    這篇文章主要介紹了Java讀取無限量文件的思路,文章還提供了完整實(shí)現(xiàn)代碼和核心優(yōu)化點(diǎn)解析,包括NIO.2替代傳統(tǒng)IO、分場(chǎng)景讀取、自定義線程池等,需要的朋友可以參考下
    2026-03-03
  • Springboot?中使用Sentinel的詳細(xì)步驟

    Springboot?中使用Sentinel的詳細(xì)步驟

    文章介紹了如何在SpringBoot中使用Sentinel進(jìn)行限流和熔斷降級(jí),首先添加依賴,配置Sentinel控制臺(tái)地址,定義受保護(hù)的資源,配置流控規(guī)則,啟動(dòng)Sentinel控制臺(tái)和SpringBoot應(yīng)用,最后測(cè)試和監(jiān)控,感興趣的朋友一起看看吧
    2025-02-02
  • Java的SpringMVC中控制器返回XML數(shù)據(jù)問題

    Java的SpringMVC中控制器返回XML數(shù)據(jù)問題

    這篇文章主要介紹了Java的SpringMVC中控制器返回XML數(shù)據(jù)問題,控制器是處理HTTP請(qǐng)求的組件,它們接收來自客戶端的請(qǐng)求,并將其轉(zhuǎn)換為適當(dāng)?shù)捻憫?yīng),這些響應(yīng)可以是動(dòng)態(tài)生成的?HTML?頁面,也可以是JSON或XML格式的數(shù)據(jù),需要的朋友可以參考下
    2023-07-07
  • Java超詳細(xì)分析講解final關(guān)鍵字的用法

    Java超詳細(xì)分析講解final關(guān)鍵字的用法

    關(guān)于final關(guān)鍵字,它也是我們一個(gè)經(jīng)常用的關(guān)鍵字,可以修飾在類上、或者修飾在變量、方法上,以此看來定義它的一些不可變性!像我們經(jīng)常使用的String類中,它便是final來修飾的類,并且它的字符數(shù)組也是被final所修飾的。但是一些final的一些細(xì)節(jié)你真的了解過嗎
    2022-06-06
  • 最安全的加密算法Bcrypt防止數(shù)據(jù)泄露詳解

    最安全的加密算法Bcrypt防止數(shù)據(jù)泄露詳解

    這篇文章主要為大家介紹了最安全的加密算法Bcrypt防止數(shù)據(jù)泄露詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 完整的醫(yī)院就診掛號(hào)系統(tǒng)基于Spring MVC + Spring + MyBatis實(shí)現(xiàn)

    完整的醫(yī)院就診掛號(hào)系統(tǒng)基于Spring MVC + Spring + MyBatis實(shí)現(xiàn)

    這篇文章主要介紹了基于Spring MVC + Spring + MyBatis實(shí)現(xiàn)的醫(yī)院就診掛號(hào)系統(tǒng),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • DWR異常情況處理常見方法解析

    DWR異常情況處理常見方法解析

    這篇文章主要介紹了DWR異常情況處理常見方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java Springboot的目的你知道嗎

    Java Springboot的目的你知道嗎

    在本篇文章中小編給大家分析了Java中Spring Boot的優(yōu)勢(shì)以及相關(guān)知識(shí)點(diǎn)內(nèi)容,興趣的朋友們可以學(xué)習(xí)參考下,希望能夠給你帶來幫助
    2021-09-09
  • SpringBoot集成PageHelper及使用方法詳解

    SpringBoot集成PageHelper及使用方法詳解

    這篇文章主要介紹了SpringBoot集成PageHelper及使用方法詳解,PageHelper 是一個(gè)開源的 Java 分頁插件,它可以幫助開發(fā)者簡(jiǎn)化分頁操作,本文提供部分相關(guān)代碼,需要的朋友可以參考下
    2023-10-10
  • Java微信公眾平臺(tái)開發(fā)(12) 微信用戶信息的獲取

    Java微信公眾平臺(tái)開發(fā)(12) 微信用戶信息的獲取

    這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開發(fā)第十二步,微信用戶信息的獲取,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04

最新評(píng)論

平遥县| 蓬安县| 南城县| 娄底市| 利辛县| 涞水县| 博罗县| 仪陇县| 灌南县| 碌曲县| 裕民县| 临朐县| 英吉沙县| 墨竹工卡县| 柳林县| 桃园市| 揭西县| 泰安市| 富阳市| 临夏市| 惠东县| 区。| 金阳县| 冷水江市| 云林县| 钦州市| 皮山县| 巧家县| 上犹县| 茶陵县| 应用必备| 岑溪市| 探索| 芷江| 富裕县| 乐安县| 鹿邑县| 宁乡县| 得荣县| 河池市| 南召县|