深入解析 Spring 框架中的事務傳播行為

目錄

(一)REQUIRED

(二)SUPPORTS

(三)MANDATORY

(四)REQUIRES_NEW

(五)NOT_SUPPORTED

(六)NEVER

(七)NESTED


在 Spring 框架中,事務管理是一個至關重要的部分,而事務傳播行為則是其中的核心概念之一。它決定了事務在多個方法調用之間的傳播方式,對于確保數據的一致性和完整性具有關鍵作用。下面將詳細介紹 Spring 框架中的七種事務傳播行為,并結合使用場景說明其重要性。

(一)REQUIRED

  1. 定義:如果當前存在事務,就加入該事務;如果當前沒有事務,就創建一個新的事務。這是最常見的選擇,也是 Spring 的默認傳播行為。
  2. 使用場景示例:在一個電商系統中,用戶下單操作涉及訂單創建、庫存扣除和支付記錄等多個步驟。這些步驟需要在同一個事務中完成,以確保數據的一致性。如果在某個步驟出現異常,整個事務應該回滾。此時,可以使用 REQUIRED 傳播行為來保證這些操作在同一個事務中執行。例如:
@Service
public class OrderService {@Autowiredprivate InventoryService inventoryService;@Autowiredprivate PaymentService paymentService;@Transactional(propagation = Propagation.REQUIRED)public void createOrder(Order order) {inventoryService.reduceStock(order.getProductId(), order.getQuantity());paymentService.processPayment(order.getAmount());// 其他訂單處理邏輯}
}

在這個例子中,createOrder 方法使用了 REQUIRED 傳播行為。如果調用該方法時已經存在一個事務(例如,在另一個服務方法中開啟了事務),那么 createOrder 方法將加入到這個已有的事務中;如果沒有現有的事務,它將創建一個新的事務來執行訂單創建的邏輯。

(二)SUPPORTS

  1. 定義:如果當前存在事務,就加入該事務;如果當前沒有事務,就以非事務方式執行。
  2. 使用場景示例:在一些對性能要求較高且不需要強制事務保證的場景中,可以使用 SUPPORTS 傳播行為。例如,在一個日志記錄系統中,記錄日志操作通常不需要事務支持,但如果在事務環境中調用日志記錄方法,可以讓它參與到當前事務中。假設有一個系統,在進行業務操作的同時需要記錄一些日志信息到數據庫。可以使用 SUPPORTS 傳播行為的服務方法來實現:
@Service
public class LoggingService {@Autowiredprivate LogRepository logRepository;@Transactional(propagation = Propagation.SUPPORTS)public void recordLog(String message) {Log log = new Log();log.setMessage(message);log.setTimestamp(new Date());logRepository.save(log);}
}

當在事務環境中調用 recordLog 方法時,它會參與到當前事務中;如果在非事務環境中調用,它會以非事務的方式執行,不會開啟新的事務。

(三)MANDATORY

  1. 定義:如果當前存在事務,就加入該事務;如果當前沒有事務,就拋出異常。
  2. 使用場景示例:適用于必須依賴于外部事務才能執行的場景。例如,在銀行轉賬系統中,轉賬操作需要在賬戶服務的事務中進行,以確保兩個賬戶的余額更新操作要么同時成功,要么同時失敗。假設有一個賬戶服務類:
@Service
public class AccountService {@Autowiredprivate AccountRepository accountRepository;@Transactional(propagation = Propagation.MANDATORY)public void transfer(Long fromAccountId, Long toAccountId, BigDecimal amount) {Account fromAccount = accountRepository.findById(fromAccountId);Account toAccount = accountRepository.findById(toAccountId);fromAccount.setBalance(fromAccount.getBalance().subtract(amount));toAccount.setBalance(toAccount.getBalance().add(amount));accountRepository.save(fromAccount);accountRepository.save(toAccount);}
}

當調用 transfer 方法時,如果當前沒有事務存在,就會拋出異常,因為這個方法必須在事務環境中執行,以確保轉賬操作的原子性。

(四)REQUIRES_NEW

  1. 定義:總是創建一個新的事務。如果當前存在事務,就把當前事務掛起。
  2. 使用場景示例:在一些需要獨立于當前事務執行的操作中非常有用。例如,在一個訂單系統中,創建訂單后需要發送一封確認郵件。發送郵件的操作應該在一個新的事務中執行,以避免郵件發送失敗影響訂單的創建。假設有一個郵件服務類:
@Service
public class EmailService {@Autowiredprivate EmailRepository emailRepository;@Transactional(propagation = Propagation.REQUIRES_NEW)public void sendConfirmationEmail(Order order) {Email email = new Email();email.setTo(order.getCustomerEmail());email.setSubject("Order Confirmation");email.setBody("Your order has been processed.");emailRepository.save(email);}
}

sendConfirmationEmail 方法被調用時,無論調用者是否在事務中,它都會創建一個新的事務來執行發送郵件的操作。這樣即使郵件發送失敗,也不會影響到訂單的創建事務。

(五)NOT_SUPPORTED

  1. 定義:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
  2. 使用場景示例:適用于那些不應該與現有事務關聯的操作,比如讀取數據或執行一些不需要事務支持的計算任務。例如,在一個數據分析系統中,查詢某個統計數據的方法可以使用 NOT_SUPPORTED 傳播行為,以避免對正在進行的事務造成不必要的干擾:
@Service
public class DataAnalysisService {@Autowiredprivate DataRepository dataRepository;@Transactional(propagation = Propagation.NOT_SUPPORTED)public BigDecimal calculateAverageValue() {List<Data> allData = dataRepository.findAll();BigDecimal sum = allData.stream().map(Data::getValue).reduce(BigDecimal.ZERO, BigDecimal::add);return sum.divide(new BigDecimal(allData.size()), 2, RoundingMode.HALF_UP);}
}

在這個例子中,calculateAverageValue 方法在執行時會掛起任何現有的事務,以非事務的方式計算平均值。

(六)NEVER

  1. 定義:以非事務方式執行,如果當前存在事務,則拋出異常。
  2. 使用場景示例:用于確保某個操作絕對不與現有事務關聯的場景。例如,在一個系統中,某些只讀操作可能不希望受到事務的影響,因為它們可能會被頻繁調用且不需要事務的一致性保證。假設有一個緩存服務類,其中的緩存加載方法可以使用 NEVER 傳播行為:
@Service
public class CacheService {@Autowiredprivate CacheManager cacheManager;@Transactional(propagation = Propagation.NEVER)public void loadCache() {// 從外部數據源加載數據到緩存中的邏輯}
}

loadCache 方法被調用時,如果當前存在事務,就會拋出異常,因為它不允許在事務環境中執行。

(七)NESTED

  1. 定義:如果當前存在事務,則在嵌套事務內執行;如果當前沒有事務,則按 REQUIRED 屬性執行。
  2. 使用場景示例:在一些復雜的業務場景中,需要在現有事務的基礎上再開啟一個子事務,以實現更細粒度的事務控制。例如,在一個大型項目中,某個模塊可能需要在另一個模塊的事務基礎上進行一些額外的操作,但又希望這些操作有自己的事務邊界。假設有一個子模塊服務類:
@Service
public class SubModuleService {@Autowiredprivate SubModuleRepository subModuleRepository;@Transactional(propagation = Propagation.NESTED)public void performSubOperation(Long subModuleId) {SubModule subModule = subModuleRepository.findById(subModuleId);// 進行子模塊相關的操作邏輯}
}

performSubOperation 方法在現有事務中被調用時,它會在一個嵌套事務中執行;如果沒有現有事務,它會像使用 REQUIRED 傳播行為一樣創建一個新的事務。

Spring 框架中的七種事務傳播行為為開發者提供了靈活的事務管理機制,能夠適應各種不同的業務場景。通過合理選擇和應用這些傳播行為,可以更好地確保數據的一致性和完整性,提高系統的可靠性和穩定性。在實際開發中,需要根據具體的業務需求仔細考慮和選擇合適的事務傳播行為,以實現最佳的事務管理效果。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66655.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66655.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66655.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

60,【1】BUUCF web [RCTF2015]EasySQL1

先查看源碼 1&#xff0c;changepwd&#xff08;修改密碼&#xff09; <?php // 開啟會話&#xff0c;以便使用會話變量 session_start();// 設置頁面的內容類型為 HTML 并使用 UTF-8 編碼 header("Content-Type: text/html; charsetUTF-8");// 引入配置文件&…

高并發內存池_CentralCache(中心緩存)和PageCache(頁緩存)申請內存的設計

三、CentralCache&#xff08;中心緩存&#xff09;_內存設計 &#xff08;一&#xff09;Span的創建 // 頁編號類型&#xff0c;32位下是4byte類型&#xff0c;64位下是8byte類型 // #ifdef _WIN64 typedef unsigned long long PageID; #else _WIN32 typedef size_t PageI…

SimpleHelp遠程管理軟件存在任意文件讀取漏洞(CVE-2024-57727)

免責聲明: 本文旨在提供有關特定漏洞的深入信息,幫助用戶充分了解潛在的安全風險。發布此信息的目的在于提升網絡安全意識和推動技術進步,未經授權訪問系統、網絡或應用程序,可能會導致法律責任或嚴重后果。因此,作者不對讀者基于本文內容所采取的任何行為承擔責任。讀者在…

2024年終總結-行到水窮處,坐看云起時

依然是——關于我 我&#xff0c;坐標山東青島&#xff0c;一位無名的Java Coder&#xff0c;你可以叫我Debug.c亦或者種棵代碼技術樹。在此不過多贅述關于我&#xff0c;更多的關于我請移步我的2023年年終總結。 2023年終總結-輕舟已過萬重山 2024年OKR完成情況 2023年年末…

AI編程工具使用技巧:在Visual Studio Code中高效利用阿里云通義靈碼

AI編程工具使用技巧&#xff1a;在Visual Studio Code中高效利用阿里云通義靈碼 前言一、通義靈碼介紹1.1 通義靈碼簡介1.2 主要功能1.3 版本選擇1.4 支持環境 二、Visual Studio Code介紹1.1 VS Code簡介1.2 主要特點 三、安裝VsCode3.1下載VsCode3.2.安裝VsCode3.3 打開VsCod…

代碼隨想錄day14

二叉樹的反轉&#xff0c;采用迭代&#xff0c;只能用前序和后序遍歷 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(i…

1月21日星期二今日早報簡報微語報早讀

1月21日星期二&#xff0c;農歷臘月廿二&#xff0c;早報#微語早讀。 1、多地官宣&#xff1a;2025年可有序、限時或在限定區域燃放煙花爆竹&#xff1b; 2、TikTok恢復在美服務&#xff1b;特朗普提出繼續運營TikTok方案&#xff0c;外交部&#xff1a;若涉及收購中國企業應…

計算機組成原理——數據表示(一)

生活是一道長長的旅程&#xff0c;充滿了挑戰和困難。然而&#xff0c;我們必須堅持下去&#xff0c;努力前進。無論遇到什么困難&#xff0c;我們都要勇敢面對&#xff0c;永不放棄。只有通過不斷的努力和堅持&#xff0c;我們才能夠取得成功。在這個旅程中&#xff0c;我們可…

【數據結構】雙向循環鏈表實現簡易圖書管理系統的增刪改查

圖書管理系統 使用雙向循環鏈表實現一個簡單的圖書管理系統&#xff0c;圖書管理系統有如下功能&#xff1a; 1.添加書籍 2.刪除書籍 3.修改書籍信息 4.查詢書籍信息 5.借書 6.還書 #include <stdio.h> #include <stdlib.h> #include <string.h>// 書籍結構體…

強化學習入門--基本概念

強化學習基本概念 grid-world example 這個指的是一個小機器人&#xff08;agent&#xff09;在一個網格區域&#xff08;存在邊界&#xff09;&#xff0c;網格中存在需要躲避的格子和目標格子&#xff0c;我們的目的就是找到到達目標格子的最短路徑 state 表示智能體相對…

STMCubeMX配置STM32F103ZET6

1 配置時鐘 配置RCC。 配置 SYS。將Timebase Source配置為TIM1, SysTick留給FreeRTOS用。 注意: 由于第一次配置的時候忘記配置這個步驟,導致工程第一次燒錄成功后,后面一直無法燒錄,報以下錯誤: keil no target connect Error: Flash Download failed - Target DLL h…

OFD 套版生成原理與 C# 實現詳解

1. 引言 OFD&#xff08;Open Fixed-layout Document&#xff09;是一種基于 XML 的開放版式文檔格式&#xff0c;主要用于電子文檔的存儲和交換。與 PDF 類似&#xff0c;OFD 是一種固定版式文檔格式&#xff0c;能夠確保文檔在不同設備和平臺上顯示的一致性。OFD 格式廣泛應…

Leetcode:2239

1&#xff0c;題目 2&#xff0c;思路 循環遍歷滿足條件就記錄&#xff0c;最后返回結果值 3&#xff0c;代碼 public class Leetcode2239 {public static void main(String[] args) {System.out.println(new Solution2239().findClosestNumber(new int[]{-4, -2, 1, 4, 8})…

C語言之斗地主游戲

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 總有人間一兩風&#xff0c;填我十萬八千夢。 &#x1f680; 路漫漫其修遠兮&#xff0c;吾將上下而求索。 ? C語言之斗地主游戲 目錄 程序概述程序設計 Card類CardGroup類Player類LastCards類Land…

python編程-OpenCV(圖像讀寫-圖像處理-圖像濾波-角點檢測-邊緣檢測)圖像變換

形態變換 圖像處理中的形態學操作是處理圖像結構的有效方法。以下是一些常見的形態學操作的介紹及其在 OpenCV 中的實現示例。 1. 腐蝕&#xff08;Erosion&#xff09; 腐蝕操作通過消除圖像邊界來減少圖像中的白色區域&#xff08;前景&#xff09;&#xff0c;使物體的邊…

【Prometheus】PromQL進階用法

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…

SiamCAR(2019CVPR):用于視覺跟蹤的Siamese全卷積分類和回歸網絡

原文標題:SiamCAR: Siamese Fully Convolutional Classification and Regression for Visual Tracking 中文標題:SiamCAR:用于視覺跟蹤的Siamese全卷積分類和回歸 代碼地址: https://github.com/ohhhyeahhh/SiamCAR Abstract 通過將視覺跟蹤任務分解為兩個子問題,…

計算機網絡介質訪問控制全攻略:從信道劃分到協議詳解!!!

一、信道劃分介質訪問控制 介質訪問控制&#xff1a;多個節點共享同一個“總線型”廣播信道時&#xff0c;可能發生“信號沖突” 應該怎么控制各節點對傳輸介質的訪問&#xff0c;才能減少沖突&#xff0c;甚至避免沖突? 時分復用(TDM) 時分復用&#xff1a;將時間分為等長的“…

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm監控配置

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm監控配置 1.Prometheus部署1.2.Prometheus修改默認端口 2.grafana可視化頁面部署3.alertmanager部署4.監控配置4.1.主機監控node-exporter4.2.監控mysql數據庫mysqld_exporter4.3.監控mongod數據庫mongodb_expo…

基于tldextract提取URL里的子域名、主域名、頂級域

TLD是TopLevel Domain的縮寫。?tldextract? 是一個用于從URL中提取子域、主域名和頂級域&#xff08;TLD&#xff09;的Python庫。它利用公共后綴列表&#xff08;Public Suffix List&#xff09;來確保即使是復雜或不常見的URL結構也能被正確解析。tldextract能夠處理包括IC…