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

炸裂!@Transactional遇上@Async:是"王炸組合"還是"致命事故"

開發 前端
@Transactional?是Spring事務管理的核心注解,用于聲明方法需要在事務上下文中執行,確保數據庫操作的原子性(ACID)。它通過AOP代理實現,默認基于數據庫連接的事務傳播機制(如PROPAGATION_REQUIRED)。

環境:SpringBoot3.4.2

1. 簡介

在Spring Boot開發中,@Transactional和@Async是兩個高頻使用的注解,分別服務于不同的場景。

@Transactional 是Spring事務管理的核心注解,用于聲明方法需要在事務上下文中執行,確保數據庫操作的原子性(ACID)。它通過AOP代理實現,默認基于數據庫連接的事務傳播機制(如PROPAGATION_REQUIRED)。

@Async 是Spring異步任務的核心注解,用于將方法標記為異步執行,本質是通過線程池啟動新線程處理任務,避免阻塞主線程,提升系統吞吐量。

當我們寫出如下的代碼后是否存在問題呢?

@Transactional
@Async
public void processProduct(Product product) {
  this.productRepository.saveAndFlush(product) ;
  this.emailService.send() ;
}
@Service
public class EmailService {
  public void send() {
    System.err.printf("%s - 發送郵件", Thread.currentThread().getName()) ;
    System.err.println(1 / 0) ;
  }
}

EmailService#send方法中我們模擬了異常拋出,執行上面的processProduct方法事務是正常執行還是回滾呢?

2.問題復現

2.1 單元測試

通過如下單元測試:

@Resource
private ProductService productService ;
@Test
public void  testCreateProduct() {
  Product product = new Product("Spring全家桶實戰案例源碼", 70D);
  this.productService.processProduct(product) ;
}

數據庫初始狀態如下:

圖片圖片

執行結果

圖片圖片

圖片

程序拋出異常后,數據庫中未插入任何數據,此結果完全符合預期要求。

這一現象表明,在默認配置條件下,@Transactional 與 @Async 這兩個注解能夠實現良好的協同運作,共同達成預期的業務邏輯處理效果。

2.2 錯誤情況

我們知道@Transactional 與 @Async 2個注解底層的實現都是通過AOP實現的,那么接下來,我們進行如下的配置修改:

@Configuration
@EnableAsync(order = Ordered.HIGHEST_PRECEDENCE)
public class AsyncConfig {
}

將@EnableAsync注解的order屬性設置為最高優先級(值越小,優先級越高)。再次運行上面的測試程序,執行結果如下(先將數據庫中的數據清空):

圖片

錯誤還是一樣的錯誤。

圖片圖片

但是數據庫中成功插入了數據,也就是事務沒有回滾。

3. 原因分析

在上述場景中已明確,默認情況下 @Transactional 與 @Async 可正常協同運作,若調整 @EnableAsync 的 order 屬性,事務會失效。

接下來,我們將進行底層原理的分析。

3.1 代理創建的原理

當項目中引入spring-boot-starter-aop時,會自動通過@EnableAspectJAutoProxy注解開啟代理功能,其實就是注冊了一個BeanPostProcessor處理器:AnnotationAwareAspectJAutoProxyCreator。

有了處理器后還需要切面,而在Spring中定義切面的方式有2種:

  • 使用 @Aspect 聲明的高級切面
    通過該注解聲明的切面最終會被轉換為低級切面Advisor。
  • 通過實現 Advisor 接口實現低級切面

總結:代理對象的創建是通過BeanPostProcessor+Advisor實現。

3.2 @Transactional底層實現

當我們項目中引入相關數據庫操作的starter時,如:spring-boot-starter-data-jpa或者spring-boot-starter-data-jdbc。底層的自動配置會通過@EnableTransactionManagement注解開啟@Transactional注解的的事務功能。

而@EnableTransactionManagement注解會自動的注冊,BeanFactoryTransactionAttributeSourceAdvisor切面。同時還會注冊InfrastructureAdvisorAutoProxyCreator處理器,但是AnnotationAwareAspectJAutoProxyCreator處理器的優先級高于InfrastructureAdvisorAutoProxyCreator,所以最終底層最終使用的BeanPostProcessor處理將是AnnotationAwareAspectJAutoProxyCreator。

總結:@Transactional事務注解將通過AnnotationAwareAspectJAutoProxyCreator + BeanFactoryTransactionAttributeSourceAdvisor創建代理對象。

3.3 @Async底層原理

要使用異步功能,我們需要通過@EnableAsync開啟功能,而該注解會自動注冊:AsyncAnnotationBeanPostProcessor處理器,而切面則是AsyncAnnotationAdvisor。

但是該處理器會先判斷當前的類是不是已經是代理對象了,如果是則只是將AsyncAnnotationAdvisor添加到當前的切面集合中,如下源碼:

圖片圖片

那這時候是不是就是看處理@Async和@Transactional注解的處理器BeanPostProcessor誰先執行了?!

3.4 處理器執行順序

AnnotationAwareAspectJAutoProxyCreator處理器默認注冊的時候設置的優先級是最高優先級,如下源碼:

圖片圖片

默認情況,通過debug查看執行順序

圖片圖片

通過這樣的執行順序,處理@Async異步任務時,這將會先開啟一個異步線程,那么后續的攔截器再執行的時候都將會在這個異步線程中,那么這樣也就保證了事務的正確性。

當我們通過@EnableAsync(order = Ordered.HIGHEST_PRECEDENCE)調整順序后,查看BeanPostProcessor執行順序:

圖片圖片

當處理 @Async 注解的處理器先執行時,會為對應 Bean 創建代理對象。待處理 @Transactional 注解的處理器執行時,因對象已為代理,會基于原始類再生成代理(其 targetSource 指向 @Async 代理對象)。最終執行業務代碼時,@Transactional 代理先觸發切面邏輯(開啟事務于主線程),隨后 @Async 代理開啟異步線程。由于事務與業務操作分屬不同線程,事務無法隨異常觸發回滾。

總結:默認你不調整執行順序那么@Transactional+@Async能很好的協同工作。

4. 新特性

從Spring 6.2起,@EnableTransactionManagement增加了一個屬性配置,可以全局控制異常回滾策略,不用再每一個@Transactional注解上進行配置回滾策略了。

@Configuration
@EnableTransactionManagement(
  rollbackOn = RollbackOn.ALL_EXCEPTIONS)
public class TxConfig {
}

RollbackOn支持2種類型,如下:

public enum RollbackOn {
  RUNTIME_EXCEPTIONS,
  ALL_EXCEPTIONS
}


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

2022-09-29 13:52:55

WindowsPython代碼

2025-04-16 02:20:00

2024-03-29 08:56:47

2023-05-06 08:23:36

ChatGPT自然語言技術

2021-09-08 15:02:28

人工智能AIRFID

2021-03-22 17:00:15

區塊鏈NFT數字資產

2012-06-01 11:19:26

2022-09-15 11:56:36

Javalua開發

2024-11-22 13:40:00

2024-12-09 09:37:46

2021-07-14 10:14:25

Docker IDEA開發

2024-05-28 08:25:09

2018-10-24 16:25:57

2018-03-17 17:33:13

云計算AI人工智能

2024-04-15 12:28:00

AI模型

2025-02-17 09:20:00

AI微信模型

2024-07-22 14:09:22

@AsyncJava

2025-02-25 10:08:38

2016-11-10 07:50:55

群暉云端Office

2019-08-05 10:15:33

系統緩存架構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品一区二区av | 日韩久久久久 | 日韩精品一区二区久久 | 欧美精品一区二区三区在线播放 | 国产在线拍偷自揄拍视频 | 欧美亚洲一区二区三区 | 免费色网址 | 欧美久久精品 | 国产精品美女久久久久aⅴ国产馆 | 中文字幕一区二区三区四区五区 | www.久久99| 黄色一级大片在线免费看产 | 久久久久久综合 | 亚洲免费在线观看 | 国产一区二区在线视频 | 精品久久ai电影 | 日本在线中文 | 精品久久久久久亚洲国产800 | 日韩成人一区 | 成人免费观看男女羞羞视频 | 亚洲 自拍 另类 欧美 丝袜 | 又黄又爽的网站 | 午夜一级大片 | 亚洲精品中文字幕 | 亚洲视频www | 亚洲成人久久久 | 91pron在线 | 天天天操 | av入口| 久久久久久国产精品免费免费男同 | 一级黄在线观看 | 久久成人人人人精品欧 | 欧美乱人伦视频 | 精品视频久久久久久 | 久久久99精品免费观看 | 91精品国产综合久久久久久丝袜 | 天天综合天天 | 欧产日产国产精品视频 | 中文字幕日韩一区 | 亚洲一区二区三区在线视频 | 成人一级毛片 |