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

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

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

1.前言

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

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

因此,在實際項目開發(fā)中,我們應該盡量避免大事務的情況。

2.什么是大事務

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

3.解決辦法

3.1.少用@Transactional注解

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

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

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

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

那可以使用編程式事務,在spring項目中使用TransactionTemplate類的對象,手動執(zhí)行事務。

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

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

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

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

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

可以用這個TransactionTemplate來解決!

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

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

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

在一個Service內部,事務方法之間的嵌套調用,普通方法和事務方法之間的嵌套調用,都不會開啟新的事務。是因為聲明式事務來實現(xiàn)事務控制,當我們通過this調用普通方法時,是通過原始對象而不是代理對象調用的方法,導致事務

不過這邊事務是失效的,因為直接方法調用使用的還是原始對象,所以事務不會生效。

那該怎么解決呢?

1.新加Service方法

這個方法非常簡單,只需要新加Service方法,把@Transactional注解加到新Service方法上,把需要事務執(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內部的三級緩存保證了它,不會出現(xiàn)循環(huán)依賴問題。

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

通過在該Service類中使用AOPProxy獲取代理對象,實現(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ǎng)絡不穩(wěn)定,遠程調其他系統(tǒng)響應時間可能比較長,這就是大事務!

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

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

遠程調用的代碼可能耗時較長,切記一定要放在事務之外。

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

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

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

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

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

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

3.5.非事務執(zhí)行

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

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

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

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

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

3.6.異步處理

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

看看下面這個列子:

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

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

答案是否定的。

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

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

4.總結

以上就是SpringBoot大事務問題的常用優(yōu)化方案的詳細內容,更多關于SpringBoot大事務優(yōu)化的資料請關注腳本之家其它相關文章!

相關文章

  • Java笛卡爾積算法原理與實現(xiàn)方法詳解

    Java笛卡爾積算法原理與實現(xiàn)方法詳解

    這篇文章主要介紹了Java笛卡爾積算法原理與實現(xiàn)方法,結合實例形式較為詳細的分析了笛卡爾積算法的原理及java定義與使用笛卡爾積算法的相關操作技巧,需要的朋友可以參考下
    2017-12-12
  • Spring框架中@PostConstruct注解詳解

    Spring框架中@PostConstruct注解詳解

    在Spring項目經(jīng)常遇到@PostConstruct注解,下面這篇文章主要給大家介紹了關于Spring框架中@PostConstruct注解的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • SpringMVC實現(xiàn)登錄與注冊功能的詳細步驟

    SpringMVC實現(xiàn)登錄與注冊功能的詳細步驟

    本文介紹了如何通過Maven配置依賴,創(chuàng)建前端登錄和注冊頁面,并實現(xiàn)后端邏輯,詳細步驟包括配置文件、創(chuàng)建User類、配置中文過濾器及DispatcherServlet,并使用Spring?MVC和JQuery處理前端請求,需要的朋友可以參考下
    2024-11-11
  • 分析講解SpringMVC注解配置如何實現(xiàn)

    分析講解SpringMVC注解配置如何實現(xiàn)

    這篇文章主要介紹了本文要介紹用注解方式代替web.xml與SpringMVC的配置文件,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • java通過釘釘機器人發(fā)消息的實現(xiàn)示例

    java通過釘釘機器人發(fā)消息的實現(xiàn)示例

    本文主要介紹了java通過釘釘機器人發(fā)消息的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09
  • 在IDEA中配置Selenium和WebDriver的具體操作

    在IDEA中配置Selenium和WebDriver的具體操作

    在自動化測試領域Selenium是一款非常流行的開源工具,它支持多種瀏覽器,并提供了豐富的API供開發(fā)者使用,而WebDriver則是Selenium的一個重要組件,它負責驅動瀏覽器執(zhí)行測試腳本,這篇文章主要給大家介紹了在IDEA中配置Selenium和WebDriver的具體操作,需要的朋友可以參考下
    2024-10-10
  • Java并發(fā)編程Semaphore計數(shù)信號量詳解

    Java并發(fā)編程Semaphore計數(shù)信號量詳解

    這篇文章主要介紹了Java并發(fā)編程Semaphore計數(shù)信號量詳解,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • Java如何獲取發(fā)送請求的電腦的IP地址

    Java如何獲取發(fā)送請求的電腦的IP地址

    文章介紹了如何通過HttpServletRequest獲取客戶端IP地址,特別是當客戶端通過代理訪問時,如何使用x-forwarded-for頭來獲取真實的IP地址
    2024-11-11
  • springBoot項目配置文件加載優(yōu)先級及同配置覆蓋問題詳解

    springBoot項目配置文件加載優(yōu)先級及同配置覆蓋問題詳解

    SpringBoot配置?件可以放置在多種路徑下,不同路徑下的配置優(yōu)先級有所不同,下面這篇文章主要給大家介紹了關于springBoot項目配置文件加載優(yōu)先級及同配置覆蓋問題的相關資料,需要的朋友可以參考下
    2023-05-05
  • SpringBoot基于Mybatis-Plus自動代碼生成

    SpringBoot基于Mybatis-Plus自動代碼生成

    這篇文章主要介紹了SpringBoot基于Mybatis-Plus自動代碼生成,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04

最新評論