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

性能調優!Spring Boot 選擇正確的事務方式,提升接口響應速度

開發 前端
編程式事務提供了對事務的細粒度控制。它允許開發人員在代碼中明確地定義事務的開始、提交和回滾,從而可以精確地控制事務的邊界和行為。這對于需要精確控制事務邏輯的場景非常有用,例如在復雜的業務邏輯中,可能需要根據不同的條件來決定是否提交或回滾事務。

環境:SpringBoot2.7.18

1. 編程方式與聲明方式

聲明式工作中用的最多,因為太過方便,你甚至都不需要做任何的配置。

@Transactional
public void save() {
  // todo
}

編程方式,用的相對較少,因為比起聲明式要麻煩點(寫的代碼多了);但是如果能結合適當的場景那么這種編程的方式會給你系統代理性能的提升。

@Resource
private TransactionTemplate template ;


public void save() {
  // todo
  template.execute(new TransactionCallback<Object>() {
    public Object doInTransaction(TransactionStatus status) {
       // todo
    }
  } ;
  // todo
}

上面兩種對事務的使用方式非常明顯大家一般都不會選擇使用編程的方式。

編程事務應用場景

  • 細粒度控制:編程式事務提供了對事務的細粒度控制。它允許開發人員在代碼中明確地定義事務的開始、提交和回滾,從而可以精確地控制事務的邊界和行為。這對于需要精確控制事務邏輯的場景非常有用,例如在復雜的業務邏輯中,可能需要根據不同的條件來決定是否提交或回滾事務。
  • 非標準事務管理:當事務管理邏輯不符合標準的事務模型時,編程式事務是一個很好的選擇。例如,在某些特殊情況下,可能需要在一個方法中執行多個數據庫操作,并且這些操作需要被劃分到不同的事務中。在這種情況下,如果使用了聲明式事務只能控制一個數據源,沒法對多個數據源進行控制。這里只是舉例,這種情況屬于分布式事務了,應該考慮如何保證事務的一致性了。

聲明式事務應用場景

  • 簡化事務管理:聲明式事務通過注解定義事務規則,使得事務管理變得簡化。它不需要在業務邏輯代碼中顯式地編寫事務管理的代碼,從而減少了代碼的復雜性。
  • 標準事務管理:聲明式事務通常用于標準的事務管理場景,例如數據庫的增刪改查操作。它提供了對事務的自動管理,包括自動提交和回滾事務,從而減少了開發人員對事務管理的關注。

2. 編程式事務應用

Spring提供了2中編程式的事務管理方式:

  • 使用TransactionTemplate 或 TransactionalOperator
  • 通過 TransactionManager

注意:TransactionTemplate是在命令式中使用,TransactionalOperator是在反應式中使用。

2.1 TransactionTemplate

在Spring Boot中如果你引入了如:data-jpa或者data-jdbc、data-r2dbc相關的依賴后,系統會自動的為我們配置TransactionTemplate或TransactionalOperator

源碼如下:

@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(ReactiveTransactionManager.class)
public TransactionalOperator transactionalOperator(ReactiveTransactionManager transactionManager) {
  return TransactionalOperator.create(transactionManager);
}


@Configuration(proxyBeanMethods = false)
@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
public static class TransactionTemplateConfiguration {
  @Bean
  @ConditionalOnMissingBean(TransactionOperations.class)
  public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
    return new TransactionTemplate(transactionManager);
  }
}

TransactionTemplate完整使用示例:

@Resource
private TransactionTemplate template ;
@Resource
private JdbcTemplate jdbcTemplate ;
public void save(Person person) {
  template.execute(new TransactionCallback<Object>() {
    @Override
    public Object doInTransaction(TransactionStatus status) {
      try {
        int result = jdbcTemplate.update("insert into t_person (age, name) values (?, ?)", person.getAge(), person.getName());
      } catch (Exception e) {
        e.printStackTrace() ;
        // 當發生異常后設置為回滾
        status.setRollbackOnly() ;
      }
      return "success"
    }
  }) ;
}

上面示例是有返回值的情況,如果你不需要返回值則可以將TransactionCallback替換為TransactionCallbackWithoutResult 。

屬性配置

public class PersonService {


  private final TransactionTemplate transactionTemplate ;


  public PersonService(PlatformTransactionManager transactionManager) {
    this.transactionTemplate = new TransactionTemplate(transactionManager);
    // 設置事務的隔離級別  
    this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
    // 設置事務超時時間
    this.transactionTemplate.setTimeout(30); // 30 seconds
  }
}

注意:你最好不要使用Spring容器自動配置的TransactionTemplate來進行相關屬性的配置,因為這是全局的,所有的操作都將使用這一份配置。

2.2 TransactionalOperator

方式1:

public class UserService {


  @Resource
  private R2dbcEntityTemplate template ;
  private final TransactionalOperator transactionalOperator;


  public UserService(ReactiveTransactionManager transactionManager) {
    this.transactionalOperator = TransactionalOperator.create(transactionManager);
  }


  public Mono<User> save(User user) {
    return Mono.just(user)
    .then(template.insert(user))
    .doOnNext(u -> {
      // 人為的制造異常
      System.out.println(1 / 0) ;
    })
    .as(transactionalOperator::transactional);
  }
}

在一個事務的上下文中運行。上面代碼執行后你將在控制臺看到事務回滾信息。

圖片圖片

如果沒有上面的as(transactionalOperator::transactional)操作,那么數據將會被正常的插入到數據庫中。

方式2:

public Flux<Integer> save2(User user) {
  return this.transactionalOperator.execute(new TransactionCallback<Integer>() {
    @Override
    public Mono<Integer> doInTransaction(ReactiveTransaction status) {
      return Mono.just(user)
          .then(template.insert(user))
          .doOnNext(u -> {
            System.out.println(1 / 0) ;
          })
          .doOnError(RuntimeException.class, e -> status.setRollbackOnly())
          .map(User::getUid) ;
    }
  }) ;
}

2.3 TransactionManager

public void save() {
  Person person = new Person();
  person.setAge(36);
  person.setName("張三");
  DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
  definition.setName("CustomTx") ;
  definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED) ;
  definition.setReadOnly(false) ;
  definition.setTimeout(2) ;
  TransactionStatus transactionStatus = tm.getTransaction(definition) ;
  try {
    jdbcTemplate.update("insert into t_person (age, name) values (?, ?)", person.getAge(), person.getName());
    // 制造異常
    System.out.println(1 / 0) ;
    // 提交
    tm.commit(transactionStatus) ;
  } catch (Exception e) {
    e.printStackTrace() ;
    // 回滾
    tm.rollback(transactionStatus) ;
  }
}

3. 性能對比(錯誤的應用事務)

數據庫連接配置

圖片圖片

為了看到更好的效果,這里只配置了5個連接。

3.1 基于注解方式

業務方法

@Transactional
public void save(Person person) {
  try {
    // 模擬針對Person執行其它非事務耗時操作
    TimeUnit.SECONDS.sleep(1) ;
  } catch (InterruptedException e) {}
  this.personRepository.saveAndFlush(person) ;
}

通過jmeter測試;

線程池配置

圖片圖片

測試結果

圖片圖片

吞吐量非常低,并且還出現了錯誤。該錯誤是由于在30s內沒有獲取到數據庫連接。

圖片圖片

3.2 基于編程方式

業務方法

public void save(Person person) {
  try {
    // 模擬針對Person執行其它非事務耗時操作
    TimeUnit.SECONDS.sleep(1) ;
  } catch (InterruptedException e) {}
  this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    @Override
    protected void doInTransactionWithoutResult(TransactionStatus status) {
      personRepository.saveAndFlush(person) ;
    }
  }) ;
}

jmeter配置不變,測試結果。

圖片

吞吐量大幅提升,并且沒有出現錯誤情況。

從上面的測試結果能夠充分的說明合理的使用事務方式在有些場景下是能夠非常明顯提升系統的整體性能。

總結:非事務性的操作應該拿到事務外執行,要么選擇編程事務。

責任編輯:武曉燕 來源: Springboot實戰案例錦集
相關推薦

2014-03-31 16:15:47

移動應用優化

2024-07-23 08:08:18

2019-12-09 09:34:47

緩存響應數據

2021-01-08 09:40:40

優化VUE性能

2024-12-10 00:00:05

2009-06-16 15:04:14

JSP頁面響應速度

2024-08-01 09:10:03

2025-01-16 10:48:40

2025-02-19 13:00:00

移動端觸摸事件響應速度JavaScrip

2016-02-15 10:52:46

視頻會議華為

2024-02-01 09:51:17

數據庫緩存

2022-02-22 16:21:04

Windows 11微軟

2023-09-19 10:31:09

算法數據

2011-08-29 17:16:29

Ubuntu

2011-03-10 14:40:54

LAMPMysql

2020-02-26 15:35:17

Spring Boot項目優化JVM調優

2017-07-21 08:55:13

TomcatJVM容器

2020-01-14 09:13:48

Tomcat調優配置

2022-06-13 09:45:51

Hook技術移動應用響應速度

2010-05-13 09:49:08

MySQL調優
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: www国产成人免费观看视频,深夜成人网 | 在线观看视频一区二区三区 | 九九精品久久久 | 久久久久国产一区二区三区不卡 | 中文一级片 | 欧美一区二区另类 | 97久久国产| 日韩手机在线看片 | 久久久久国产一区二区三区四区 | a亚洲精品 | 四虎影视1304t | 不卡一区二区三区四区 | 国产精品视频500部 a久久 | 午夜免费福利片 | 国产区在线观看 | 美美女高清毛片视频免费观看 | 九九久久精品视频 | 中国xxxx性xxxx产国 | 精品视频在线观看 | 欧美九九九 | 日本黄色免费片 | 欧美成人一级 | 国产一区二区在线视频 | 秋霞av国产精品一区 | 九九亚洲 | 久久成人精品视频 | 青青久在线视频 | 天天夜夜操 | 日韩美女在线看免费观看 | 国产欧美精品区一区二区三区 | 91色综合| 在线观看三级av | 亚洲网在线 | 91传媒在线观看 | 一区二区三 | 亚洲精品中文字幕中文字幕 | 一级欧美一级日韩片免费观看 | 二区中文字幕 | 成人亚洲性情网站www在线观看 | 亚洲永久 | 中文字幕日韩欧美 |