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

Spring聲明式事務(wù)(@Transactional)通過(guò)AOP實(shí)現(xiàn)過(guò)程

 更新時(shí)間:2026年05月16日 10:52:43   作者:冰糖心書房  
Spring的聲明式事務(wù)通過(guò)AOP代理技術(shù)實(shí)現(xiàn),掃描標(biāo)記了@Transactional的類或方法,為目標(biāo)對(duì)象創(chuàng)建代理,方法調(diào)用時(shí)根據(jù)配置開(kāi)啟、提交或回滾事務(wù),從而簡(jiǎn)化事務(wù)管理,提高代碼復(fù)用性和可維護(hù)性

Spring 的聲明式事務(wù) (@Transactional) 是 AOP 技術(shù)最經(jīng)典的應(yīng)用之一。

其核心思想是:通過(guò) AOP 代理,在業(yè)務(wù)代碼執(zhí)行前后,自動(dòng)地開(kāi)啟、提交或回滾事務(wù)。

下面是詳細(xì)的實(shí)現(xiàn)步驟和原理:

Step 1: 掃描與識(shí)別

當(dāng) Spring 容器啟動(dòng)時(shí):

  • 它會(huì)掃描所有的 Bean。
  • 它會(huì)尋找被 @Transactional 注解標(biāo)記的類或方法。
  • 一旦發(fā)現(xiàn)某個(gè) Bean(例如 OrderService)中含有 @Transactional 方法,Spring 就會(huì)判定這個(gè) Bean 需要事務(wù)增強(qiáng)。

Step 2: 創(chuàng)建代理對(duì)象

對(duì)于需要事務(wù)增強(qiáng)的 Bean,Spring 不會(huì)直接將原始的 OrderService 實(shí)例放入容器。相反,它會(huì):

  • 使用 AOP 框架(具體來(lái)說(shuō)是 TransactionProxyFactoryBean)為這個(gè) OrderService 創(chuàng)建一個(gè)代理對(duì)象OrderServiceProxy)。
  • 這個(gè)代理對(duì)象看起來(lái)和原始對(duì)象一模一樣(實(shí)現(xiàn)了相同的接口或繼承了相同的類),但它的內(nèi)部包含了額外的事務(wù)攔截器 (Transaction Interceptor)。
  • 最終,當(dāng)其他組件(如 Controller)通過(guò) @Autowired 注入 OrderService 時(shí),它們實(shí)際得到的是這個(gè)代理對(duì)象。

Step 3: 方法調(diào)用與攔截 (核心)

當(dāng)你的代碼調(diào)用一個(gè)被 @Transactional 注解的方法時(shí)(例如 orderServiceProxy.placeOrder()),這個(gè)調(diào)用過(guò)程會(huì)遵循一個(gè)典型的環(huán)繞通知 (@Around) 流程:

調(diào)用被代理對(duì)象攔截

你的調(diào)用首先到達(dá)的是 OrderServiceProxy,而不是原始的 OrderService

事務(wù)攔截器 (Transaction Interceptor) 被激活

代理對(duì)象中的事務(wù)攔截器(可以看作一個(gè)環(huán)繞通知)開(kāi)始工作。它的邏輯如下:

a. 【方法執(zhí)行前】準(zhǔn)備事務(wù)環(huán)境:

  • * 獲取 PlatformTransactionManager(事務(wù)管理器,如 DataSourceTransactionManager)。
  • * 檢查當(dāng)前是否存在一個(gè)已激活的事務(wù)。
  • * 根據(jù) @Transactional 注解中配置的傳播行為 (Propagation) 來(lái)決定下一步操作。例如:
  • * REQUIRED (默認(rèn)):如果當(dāng)前沒(méi)事務(wù),就開(kāi)啟一個(gè)新事務(wù) (connection.setAutoCommit(false));如果已有事務(wù),就加入它。
  • * REQUIRES_NEW掛起當(dāng)前事務(wù)(如果存在),并總是開(kāi)啟一個(gè)全新的事務(wù)。
  • * 根據(jù)注解配置設(shè)置事務(wù)的隔離級(jí)別 (Isolation)超時(shí)時(shí)間 (Timeout)、只讀狀態(tài) (Read-Only) 等。

b. 【調(diào)用目標(biāo)方法】執(zhí)行核心業(yè)務(wù)邏輯:

  • * 在 try 代碼塊中,事務(wù)攔截器會(huì)調(diào)用原始的 OrderService 對(duì)象的 placeOrder() 方法。
  • * orderRepository.save(order);
  • * stockService.decreaseStock(order.getProductId());
  • * 你的所有業(yè)務(wù)代碼都在這個(gè)事務(wù)的保護(hù)下執(zhí)行。

c. 【方法成功返回后】提交事務(wù):

  • * 如果目標(biāo)方法成功執(zhí)行完畢,沒(méi)有拋出任何異常,try 塊正常結(jié)束。
  • * 事務(wù)攔截器會(huì)捕獲到這個(gè)成功的狀態(tài),然后調(diào)用 transactionManager.commit() 來(lái)提交事務(wù)

d. 【方法拋出異常后】回滾事務(wù):

  • * 如果目標(biāo)方法在執(zhí)行過(guò)程中拋出了異常,這個(gè)異常會(huì)被 catch 塊捕獲。
  • * 事務(wù)攔截器會(huì)檢查這個(gè)異常的類型。根據(jù) @Transactional 注解的回滾規(guī)則 (Rollback Rules)
  • * 默認(rèn)情況下,如果拋出的是 RuntimeExceptionError,事務(wù)攔截器會(huì)調(diào)用 transactionManager.rollback() 來(lái)回滾事務(wù)。
  • * 如果拋出的是已檢查異常 (Checked Exception),默認(rèn)不會(huì)回滾(這個(gè)行為可以配置)。
  • * 回滾后,異常會(huì)繼續(xù)向上層拋出,以便調(diào)用方可以感知到錯(cuò)誤。

圖解實(shí)現(xiàn)原理

+----------------+
| Controller     |
+----------------+
        | 1. 調(diào)用 orderService.placeOrder()
        v
+-----------------------------------------------------------------------------+
|              OrderService 代理對(duì)象 (Proxy)                                   |
|                                                                             |
|   +---------------------------------------------------------------------+   |
|   |             事務(wù)攔截器 (Transaction Interceptor - Around Advice)      |   |
|   |                                                                     |   |
|   |    2. 【方法執(zhí)行前】                                                  |   |
|   |       - 獲取事務(wù)管理器                                                |   |
|   |       - 根據(jù)傳播行為,開(kāi)啟新事務(wù) (connection.setAutoCommit(false))     |   |
|   |                                                                     |   |
|   |    3. 【調(diào)用目標(biāo)方法】try {                                           |   |
|   |           target.placeOrder(); <---------------------------------+    |   |
|   |       }                                                          |    |   |
|   |                                                                  |    |   |
|   |    4a. 【成功返回后】catch (no exception) {                        |    |   |
|   |            transactionManager.commit(); // 提交事務(wù)              |    |   |
|   |        }                                                         |    |   |
|   |                                                                  |    |   |
|   |    4b. 【拋出異常后】catch (RuntimeException | Error) {             |    |   |
|   |            transactionManager.rollback(); // 回滾事務(wù)             |    |   |
|   |            throw ex; // 繼續(xù)拋出異常                             |    |   |
|   |        }                                                         |    |   |
|   |                                                                     |   |
|   +---------------------------------------------------------------------+   |
|                                                                             |
+-----------------------------------------------------------------------------+
        ^                                                               |
        | 5. 最終結(jié)果或異常返回給 Controller                             |
        |                                                               |
        |        +--------------------------------------------------------+
        |        |
        v        v
+--------------------------+
|  OrderService 目標(biāo)對(duì)象   |
|  (包含純粹的業(yè)務(wù)邏輯)    |
+--------------------------+

總結(jié)

  • 核心技術(shù):Spring AOP 的環(huán)繞通知 (@Around)。

關(guān)鍵角色

  • 代理對(duì)象 (Proxy):攔截方法調(diào)用。
  • 事務(wù)攔截器 (Transaction Interceptor):實(shí)現(xiàn)了具體的事務(wù)管理邏輯。
  • 事務(wù)管理器 (PlatformTransactionManager):執(zhí)行真正的事務(wù)操作(開(kāi)啟、提交、回滾)。

工作流程

  1. 代理攔截:調(diào)用被代理對(duì)象攔截。
  2. 事務(wù)開(kāi)啟:在目標(biāo)方法執(zhí)行前,根據(jù)配置開(kāi)啟事務(wù)。
  3. 業(yè)務(wù)執(zhí)行:調(diào)用原始目標(biāo)對(duì)象的業(yè)務(wù)方法。
  4. 事務(wù)提交/回滾:根據(jù)業(yè)務(wù)方法的執(zhí)行結(jié)果(成功或異常),決定是提交還是回滾事務(wù)。

通過(guò)這種方式,AOP 完美地將重復(fù)、通用的事務(wù)管理代碼從核心業(yè)務(wù)邏輯中剝離出來(lái),實(shí)現(xiàn)了高度的解耦和代碼的整潔。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解java中的static關(guān)鍵字

    詳解java中的static關(guān)鍵字

    這篇文章主要介紹了java中的static關(guān)鍵字的的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 密碼系統(tǒng)AES私鑰RSA公鑰的加解密示例

    密碼系統(tǒng)AES私鑰RSA公鑰的加解密示例

    這篇文章主要為大家詮釋并介紹了AES私鑰RSA公鑰的加解密系統(tǒng)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • SpringCloud服務(wù)接口調(diào)用OpenFeign及使用詳解

    SpringCloud服務(wù)接口調(diào)用OpenFeign及使用詳解

    這篇文章主要介紹了SpringCloud服務(wù)接口調(diào)用——OpenFeign,在學(xué)習(xí)Ribbon時(shí),服務(wù)間調(diào)用使用的是RestTemplate+Ribbon實(shí)現(xiàn),而Feign在此基礎(chǔ)上繼續(xù)進(jìn)行了封裝,使服務(wù)間調(diào)用變得更加方便,需要的朋友可以參考下
    2023-04-04
  • Java微服務(wù)無(wú)損發(fā)布生產(chǎn)實(shí)戰(zhàn)案例及驗(yàn)證

    Java微服務(wù)無(wú)損發(fā)布生產(chǎn)實(shí)戰(zhàn)案例及驗(yàn)證

    微服務(wù)架構(gòu)是一項(xiàng)在云中部署應(yīng)用和服務(wù)的新技術(shù),這篇文章主要介紹了Java微服務(wù)無(wú)損發(fā)布生產(chǎn)實(shí)戰(zhàn)及驗(yàn)證的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-10-10
  • 解決Springboot項(xiàng)目打包后的頁(yè)面丟失問(wèn)題(thymeleaf報(bào)錯(cuò))

    解決Springboot項(xiàng)目打包后的頁(yè)面丟失問(wèn)題(thymeleaf報(bào)錯(cuò))

    這篇文章主要介紹了解決Springboot項(xiàng)目打包后的頁(yè)面丟失問(wèn)題(thymeleaf報(bào)錯(cuò)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 詳解SpringBoot定制@ResponseBody注解返回的Json格式

    詳解SpringBoot定制@ResponseBody注解返回的Json格式

    這篇文章主要介紹了詳解SpringBoot定制@ResponseBody注解返回的Json格式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java GUI圖形界面開(kāi)發(fā)實(shí)現(xiàn)小型計(jì)算器流程詳解

    Java GUI圖形界面開(kāi)發(fā)實(shí)現(xiàn)小型計(jì)算器流程詳解

    本文章向大家介紹Java GUI圖形界面開(kāi)發(fā)實(shí)現(xiàn)小型計(jì)算器,主要包括布局管理器使用實(shí)例、應(yīng)用技巧、基本知識(shí)點(diǎn)總結(jié)和需要注意事項(xiàng),具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08
  • MyBatis代理Dao方式的增刪改查的實(shí)現(xiàn)小結(jié)

    MyBatis代理Dao方式的增刪改查的實(shí)現(xiàn)小結(jié)

    本文主要介紹了MyBatis代理Dao方式的增刪改查的實(shí)現(xiàn)小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • SpringCloud客戶端的負(fù)載均衡Ribbon的實(shí)現(xiàn)

    SpringCloud客戶端的負(fù)載均衡Ribbon的實(shí)現(xiàn)

    微服務(wù)架構(gòu),不可避免的存在單個(gè)微服務(wù)有多個(gè)實(shí)例,這篇文章主要介紹了SpringCloud客戶端的負(fù)載均衡Ribbon的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • Spring?boot?運(yùn)用策略模式實(shí)現(xiàn)避免多次使用if的操作代碼

    Spring?boot?運(yùn)用策略模式實(shí)現(xiàn)避免多次使用if的操作代碼

    這篇文章主要介紹了Spring?boot?運(yùn)用策略模式實(shí)現(xiàn),避免多次使用if,使用策略模式后,新加一種支付策略時(shí),只需要在策略枚舉中添加新加的策略信息,外加一個(gè)策略類即可,而不再需要添加新的if判斷,需要的朋友可以參考下
    2022-08-08

最新評(píng)論

栾川县| 外汇| 通辽市| 沾化县| 玉田县| 吴川市| 屯门区| 会昌县| 景泰县| 施秉县| 霍林郭勒市| 美姑县| 高阳县| 太原市| 浦城县| 昌邑市| 瑞丽市| 江华| 建阳市| 和龙市| 江山市| 茌平县| 广德县| 静安区| 哈尔滨市| 锦屏县| 全椒县| 勃利县| 宝清县| 和政县| 佛山市| 天祝| 洛隆县| 玉林市| 神池县| 青岛市| 元朗区| 南昌市| 揭东县| 博乐市| 库伦旗|