成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

這樣一優化系統整體性能立馬提升

數據庫 MySQL
MySQL的UPDATE語句默認會帶上一個寫鎖(Write Lock)。在MySQL中,寫鎖會阻塞其他事務對同一行的讀取和寫入操作,以確保數據的一致性和完整性。

環境:Spring5.3.23

1. 案例代碼

先看下示例代碼:

static class PersonService {
  @Resource
  private JdbcTemplate jdbcTemplate;
  /**
   * 這里的代碼,先執行了更新操作,然后執行查詢操作。
   * 業務代碼非常的簡單
   */
  @Transactional
  public void operator() {
    // 1
    int res = this.jdbcTemplate.update("update p_user t set t.address='akf' where t.id = 9000000") ;
    System.out.printf("更新: %d 條數據%n", res) ;
    // 2
    List<Map<String, Object>> users = this.jdbcTemplate.queryForObject("select * from p_user x where x.username='h4F7i4B4'", (rs, rowNum) -> {
      List<Map<String, Object>> datas = new ArrayList<>() ;
      while (rs.next()) {
        Map<String, Object> obj = new HashMap<>() ;
        obj.put("id", rs.getObject(1)) ;
        obj.put("username", rs.getObject(2)) ;
        obj.put("email", rs.getObject(3)) ;
        obj.put("password", rs.getObject(4)) ;
        obj.put("address", rs.getObject(5)) ;
        obj.put("age", rs.getObject(6)) ;
        datas.add(obj) ;
      }
      return datas ;
    }) ;
    System.out.println(users) ;
  }
}

先思考上面代碼在什么樣的場景下可以做相應的優化?

2. 環境準備

本地環境我準備了p_user表數據量2000W。

圖片圖片

數據庫索引情況:

圖片圖片

這里除了主鍵,沒有任何其它的索引。

這里不建立任何二級索引是為了模擬查詢慢的場景。

執行上面的查詢SQL:

圖片圖片

執行時間5s;感覺還好

3. 代碼分析

在上面的代碼中2個關鍵的數據庫操作分別是更新與查詢,這兩個查詢是沒有任何關聯的,相關獨立;而在整個方法上是添加了@Transaction注解,整個方法的執行都是在一個事務中執行。那么這里的查詢如果非常的慢是不是會對當前的修改記錄或者是整個p_user表造成影響呢?

結合上面的數據表情況,當前表是沒有任何索引的(除主鍵)。如果這里的查詢比較慢,會發生什么情況呢?

首先你要知道MySQL中update語句會上什么鎖?

回顧MySQL鎖:

MySQL的UPDATE語句默認會帶上一個寫鎖(Write Lock)。在MySQL中,寫鎖會阻塞其他事務對同一行的讀取和寫入操作,以確保數據的一致性和完整性。

當執行UPDATE語句時,MySQL會在相關的行上獲取寫鎖。這樣,其他事務無法修改或刪除這些行,直到寫鎖被釋放。這有助于防止在并發操作中發生數據沖突或不一致的情況。

還有點要注意mysql的鎖機制是基于事務的,所以通常我們需要在一個事務中進行操作。隨著事務的提交或回滾進行鎖的釋放

知道了update語句默認會帶上寫鎖,那么這里的update鎖的是id等于9000000的數據。前面提到了,只要事務提交或者回滾后鎖才會被釋放。

那如果這里我們接下來的查詢比較慢那是不是我們這個鎖的釋放時間就會變長,其它事務將會被阻塞。一旦發生了阻塞我們系統的整體性能可能會受到影響。這里的update語句只會對id為9000000的數據上鎖,如果咱們的更新語句是范圍的或者條件是沒有索引的那很可能就成了表鎖,那這時候系統的性能會變的非常糟糕。也就是我們對這條id為9000000的數據要鎖至少5s時間。

該如何優化上面的代碼呢?

4. 代碼優化

通過上面的分析,由于先執行了update語句,然后執行查詢語句,如果查詢比較慢那么我們的update語句形成的寫鎖(行鎖,間隙鎖或者表鎖)時間會變長,對系統的整體性能會造成影響。所以這里我們只需要將查詢和修改操作順序進行下調整即可。

@Transactional
public void operator() {
  // 1
  List<Map<String, Object>> users = this.jdbcTemplate.queryForObject("select * from p_user x where x.username='h4F7i4B4'", (rs, rowNum) -> {
    List<Map<String, Object>> datas = new ArrayList<>() ;
    while (rs.next()) {
      Map<String, Object> obj = new HashMap<>() ;
      obj.put("id", rs.getObject(1)) ;
      // ...
      datas.add(obj) ;
    }
    return datas ;
  }) ;
  System.out.println(users) ;
  // 2
  int res = this.jdbcTemplate.update("update p_user t set t.address='akf' where t.id = 9000000") ;
  System.out.printf("更新: %d 條數據%n", res) ;
}

通過上面的優化,雖然該接口自身的性能并沒有提升,但是在該接口中update語句形成的鎖時間將大大的減少(在這里查詢語句是沒有鎖的),如果同一時刻存在其它事務修改當前的數據不至于被阻塞太長時間,那其它接口的性能整體不就提高了么。

在上面的代碼中首先是2個操作互不相干,其實完全可以把不需要事務的操作放到其它方法中(注意事務失效問題)。

static class PersonService {
  @Resource
  private JdbcTemplate jdbcTemplate;
  @Resource
  private PersonService ps ;


  public void query() {
    ps.update() ;
    List<Map<String, Object>> users = this.jdbcTemplate.queryForObject("select * from p_user x where x.username='h4F7i4B4'", (rs, rowNum) -> {
      List<Map<String, Object>> datas = new ArrayList<>() ;
      while (rs.next()) {
        Map<String, Object> obj = new HashMap<>() ;
        obj.put("id", rs.getObject(1)) ;
        // ...
        datas.add(obj) ;
      }
      return datas ;
    }) ;
    System.out.println(users) ;
  }
  
  @Transactional
  public void update() {
    int res = this.jdbcTemplate.update("update p_user t set t.address='akf' where t.id = 9000000") ;
    System.out.printf("更新: %d 條數據%n", res) ;
  }
}

上面代碼己注入自己,解決在非事務方法中調用事務方法二導致事務失效。當然也可以通過AopContext來解決(不推薦),也可以把事務方法放到其它類中都可以解決。

完畢!!!

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2017-01-15 09:56:48

LinuxIO性能

2010-01-05 13:59:22

網吧交換機

2023-10-06 16:56:19

Python二進制工具

2010-02-22 10:38:44

Web交換技術

2020-11-24 20:54:17

數據

2014-06-12 19:53:08

達夢DMETLETL

2011-12-21 17:12:07

2023-09-25 08:06:44

工具非阻塞式接口

2025-02-27 10:30:00

JavaScript數組代碼

2012-07-03 10:26:30

SQL語句優化

2017-12-12 14:26:16

數據庫PostgreSQL邏輯優化

2025-01-20 09:05:00

模型推理AI

2024-09-19 08:09:37

MySQL索引數據庫

2023-03-08 07:46:53

面試官優化結構體

2009-11-16 13:59:22

Oracle優化

2024-09-04 11:04:00

SQL監控優化

2020-06-01 22:09:48

緩存緩存同步緩存誤用

2016-11-10 16:14:56

閃存HDD閃存存儲

2025-06-26 02:15:00

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩视频免费看 | 国产精品久久影院 | 国产精品毛片av | 中文字幕国产视频 | 亚洲视频免费在线观看 | 欧美九九九 | 久久精品中文字幕 | 日韩欧美国产精品 | 午夜免费网站 | 国产国产精品久久久久 | 伊人在线| av黄色免费在线观看 | 国产免费一区 | 日韩有码一区 | 日韩91 | 久久伊| 国产日韩欧美电影 | 国产在线视频一区 | 亚洲视频一区 | 成年免费大片黄在线观看一级 | 色吧综合| 亚洲国产欧美国产综合一区 | 婷婷综合 | 国产精品毛片无码 | 国产91丝袜 | 涩涩操 | xx性欧美肥妇精品久久久久久 | 免费簧片视频 | 91精品国产综合久久婷婷香蕉 | 91免费福利视频 | 91亚洲一区 | 人人玩人人添人人澡欧美 | 亚洲福利一区 | 国产精品视频偷伦精品视频 | 中国免费黄色片 | 丁香六月伊人 | 欧美在线天堂 | 精品av久久久久电影 | aaa级片 | 欧美一区二区视频 | 丝袜一区二区三区 |