2023.12.9 關于 Spring Boot 事務傳播機制詳解

目錄

事務傳播機制

七大事務傳播機制?

支持當前調用鏈上的事務

Propagation.REQUIRED

Propagation.SUPPORTS

Propagation.MANDATORY

不支持當前調用鏈上的事務

Propagation.REQUIRES_NEW

Propagation.NOT_SUPPORTED

Propagation.NEVER

嵌套事務

Propagation.NESTED

前置工作

初始化數據庫

初始化 實體類

初始化 Mapper 接口

初始化 XML 文件

?重點理解部分

NESTED 和 REQUIRED_NEW 的區別

NESTED 和 REQUIRED 的區別


事務傳播機制

  • 事務的傳播機制是指在多個事務方法之間調用時,事務如何在這些方法之間傳播

七大事務傳播機制?

支持當前調用鏈上的事務

Propagation.REQUIRED

  • 默認的事務傳播級別
  • 如果當前沒有事務,則新建一個事務,如果當前存在事務,則加入該事務

實例理解


Propagation.SUPPORTS

  • 如果當前方法沒有事務,就以非事務方式執行,如果已經存在一個事務中,則加入到這個事務中


Propagation.MANDATORY

  • 如果當前方法沒有事務,則拋出異常,如果已經存在一個事務中,則加入到這個事務中

不支持當前調用鏈上的事務

Propagation.REQUIRES_NEW

  • 創建一個新事務,如果存在當前事務,則掛起當前事務

Propagation.NOT_SUPPORTED

  • 以非事務方式執行,如果存在當前事務,則掛起當前事務

Propagation.NEVER

  • 以非事務方式執行,如果當前事務存在,則拋出異常

嵌套事務

Propagation.NESTED

  • 如果當前存在事務,則在嵌套事務中執行,否則與 REQUIRED 的操作一樣

前置工作

  • 此處為了方便下文進行代碼測試理解
  • 我們先將準備工作做好

初始化數據庫

  • 創建一個 user 表,并添加幾條用戶信息


初始化 實體類

  • 創建?User 實體類 與 數據庫的 user 表字段名相對應
import lombok.Data;@Data
public class User {private int id;private String name;private int age;private String password;private int state;
}

初始化 Mapper 接口

  • 初始化?UserMapper 接口,此處我們添加一個 add?方法

import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;@Mapper
public interface UserMapper {
//    新增用戶信息Integer add(User user);
}

初始化 XML 文件

  • 在與 UserMapper 接口相對應的 XML 文件中添加上與 add 方法 相對應的 sql 語句
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper"><insert id="add">insert into user(name,age,password) values(#{name},#{age},#{password})</insert>
</mapper>

?重點理解部分

NESTED 和 REQUIRED_NEW 的區別

  • REQUIRED_NEW 是新建一個事務并且新開始的這個事務與原有事務無關
  • 而 NESTED 是當前存在事務時會開啟一個嵌套事務
  • 在?NESTED 情況下,父事務回滾時,子事務也會回滾
  • 而 REQUIRED_NEW 情況下,原有事務回滾,不會影響新開啟的事務

實例理解

  • 我們創建一個 userController 類,并給 addUser?方法加上 REQUIRED 類型的事務
  • ?此時的 addUser 方法,將自動創建一個事務A
  • 注意我們在 addUser 中加入了一個算數異常
import com.example.demo.entity.User;
import com.example.demo.service.LoggerService;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user2")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/add")@Transactional(propagation = Propagation.REQUIRED)public String addUser(User user) {
//        調用 userService 的 add 方法int result = userService.add(user);int c = 10/0;return "add 方法:" + (result == 1 ? "新增用戶成功": "新增用戶失敗");}
}
  • 可以看到?userController 類中調用了 add 方法,該方法在 userService 中
  • 此處我們給 add 方法加上 NESTED 類型的事務
  • 因為 addUser 已經創建了一個事務A,所以此處的 add 方法將在 事務A中創建一個嵌套事務
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;//    新增用戶信息@Transactional(propagation = Propagation.NESTED)public int add(User user) {int result = userMapper.add(user);return result;}
}

運行結果:

  • 在瀏覽器中輸入對應的 URL 來訪問 addUser 方法
  • 此時我們關注的是 在?NESTED 情況下,父事務回滾時,子事務也會回滾

  • 此處正好為 addUser 方法發生了 算數異常,從而進行了回滾操作
  • 且在拋出算數異常前,就已經調用了 userService.add 方法
  • 如果此處數據庫中插入了新用戶信息,則代表子事務未進行回滾操作

  • 此時我們查看 user 表,發現新用戶未插入,即子事務進行了回滾操作,與預期結果一致

調整 add 方法的事務傳播機制

  • 我們將 add 方法改為 REQUIRES_NEW?類型的事務
  • 因為 addUser 已經創建了一個事務A,所以此處的 add 方法將會把 事務A 掛起,另外創建一個 事務B
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;//    新增用戶信息@Transactional(propagation = Propagation.REQUIRES_NEW)public int add(User user) {int result = userMapper.add(user);return result;}
}

運行結果:

  • 在瀏覽器中輸入對應的 URL 來訪問 addUser 方法
  • 此時我們關注的是 REQUIRED_NEW 情況下,原有事務回滾,不會影響新開啟的事務

  • 查看 user 表發現新增了一條用戶信息,即新開啟的事務B 未進行回滾,與預期結果一致


NESTED 和 REQUIRED 的區別

  • REQUIRED 的情況下,調用方存在事務時,則被調用發和調用方使用同一個事務
  • 那么被調用方出現異常時,由于共用同一個事務,所以無論是否 catch 異常,事務都會回滾
  • 而在 NESTTED 情況下,被調用方發生異常時,調用方可以 catch 其異常,這樣只有子事務回滾,父事務不回滾

實例理解

  • 我們創建一個 userController 類,并給 addUser?方法加上 REQUIRED 類型的事務
  • 此時的 addUser 方法,將自動創建一個事務A
  • 我們將在 userService 的 add 方法中加入一個 算數異常
  • 為了驗證 REQUIRED 的情況下,被調用方出現異常時,由于共用同一個事務,所以無論是否 catch 異常,事務都會回滾
  • 如果不捕獲?add 方法拋出的異常 事務A 肯定會進行回滾操作
  • 所以我們此處對算數異常進行捕獲,由此來看 事務A 是否還會進行回滾操作
import com.example.demo.entity.User;
import com.example.demo.service.LoggerService;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user2")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/add")@Transactional(propagation = Propagation.REQUIRED)public String addUser(User user) {int result = 0;try {
//        調用 userService 的 add 方法result = userService.add(user);}catch (Exception e){e.printStackTrace();}return "add 方法:" + (result == 1 ? "新增用戶成功": "新增用戶失敗");}
}
  • 此處我們給 add 方法加上?REQUIRED 類型的事務
  • 因為 addUser 已經創建了一個事務A,所以此處的 add 方法將會直接加入?事務A 中
  • 此處我們在 add 方法中加入了一個算數異常
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;//添加 @Service 注解 代表該類會伴隨著 項目的啟動而注入到容器中
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;//    新增用戶信息@Transactional(propagation = Propagation.REQUIRED)public int add(User user) {int result = userMapper.add(user);int a = 1/0;return result;}
}

運行結果:

  • 在瀏覽器中輸入對應的 URL 來訪問 addUser 方法

  • 查看 user 表發現沒有新增新用戶信息,即事務A進行了回滾操作,與預期結果一致

調整 add 方法的事務傳播機制

  • 我們將 add 方法改為? NESTED?類型的事務
  • 因為 addUser 已經創建了一個事務A,所以此處的 add 方法將會在 事務A 中創建一個嵌套事務
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;//添加 @Service 注解 代表該類會伴隨著 項目的啟動而注入到容器中
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;//    新增用戶信息@Transactional(propagation = Propagation.NESTED)public int add(User user) {int result = userMapper.add(user);int a = 1/0;return result;}
}

運行結果:

  • 在瀏覽器中輸入對應的 URL 來訪問 addUser 方法
  • 此處為了驗證 NESTTED 情況下,被調用方發生異常時,調用方可以 catch 其異常,這樣只有子事務回滾,父事務不回滾
  • 在瀏覽器中輸入對應的 URL 來訪問 addUser 方法

  • 我們可以看到 事務A 未進行回滾操作

  • 查看 user 表發現沒有新增新用戶信息,即子事務進行了回滾操作,與預期結果一致

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

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

相關文章

蜂窩、無線設備應用 HXG-242+、PVGA-123+、PMA-5452+、PSA-39+、PSA-14+射頻放大器(IC器件)

1、HXG-242 射頻放大器 IC 無線 LAN&#xff0c;LTE 700MHz 至 2.4GHz&#xff0c;6-SMD 模塊 HXG-242&#xff08;符合RoHS規范&#xff09;是一款先進的放大器模塊&#xff0c;結合了高動態范圍MMIC技術和優化電路&#xff0c;可在聚焦頻率范圍內提供業界領先的線性度。它采…

創建并測試第一個django項目并解決過程中遇到的問題

Django 是一個高級 Python Web 框架&#xff0c;它鼓勵快速開發和簡潔、實用的設計。它由經驗豐富的開發人員構建&#xff0c;解決了 Web 開發的大部分麻煩&#xff0c;因此您可以專注于編寫應用程序&#xff0c;而無需重新發明輪子。它是免費和開源的。 目錄 一、django項目 …

Nginx 簡單入門操作

前言:之前的文章有些過就不羅嗦了。 Nginx 基礎內容 是什么? Nginx 是一個輕量級的 HTTP 服務器,采用事件驅動、異步非阻塞處理方式的服務器,它具有極好的 IO 性能,常用于 HTTP服務器(包含動靜分離)、正向代理、反向代理、負載均衡 等等. Nginx 和 Node.js 在很多方…

pdb 調試 python 代碼

pdb python的官方調試工具; 默認下載的模塊 參考文檔 pdbpdb有官方文檔, 也有源碼, 可能閱讀python源碼更容易理解; 和gdb非常相似&#xff0c;也支持擴展; 基于bdb,cmd拓展; 代碼中設置調試點(一次性調試) 好處是可以源碼級別的調試, 對于剛了解pdb又想調試子進程的比較…

大語言模型有什么意義?亞馬遜訓練自己的大語言模型有什么用?

近年來&#xff0c;大語言模型的嶄露頭角引起了廣泛的關注&#xff0c;成為科技領域的一項重要突破。而在這個領域的巔峰之上&#xff0c;亞馬遜云科技一直致力于推動人工智能的發展。那么&#xff0c;作為一家全球科技巨頭&#xff0c;亞馬遜為何會如此注重大語言模型的研發與…

解讀 | GPT-4突然“變賴“ 是莫名其妙還是另有玄機

大家好&#xff0c;我是極智視界&#xff0c;歡迎關注我的公眾號&#xff0c;獲取我的更多前沿科技分享 邀您加入我的知識星球「極智視界」&#xff0c;星球內有超多好玩的項目實戰源碼和資源下載&#xff0c;鏈接&#xff1a;https://t.zsxq.com/0aiNxERDq 事情是這樣的&#…

初學websocket有感-待研究

https://www.bilibili.com/video/BV1KN411n7WD/ 看到一半的時候就會想到以下的問題&#xff1a; 初學websocket有感-待研究 既然每一個endPoint都是對應著一個服務器和客戶端瀏覽器的連接對象&#xff0c;那么就是說要創建很多個endPoint對象咯。 一、是否回將創建的這么多…

項目經理和產品經理哪個更有發展前景?

如果是單看“錢途”的話&#xff0c;如果是在傳統行業&#xff0c;可能差不多&#xff1b;如果是在IT行業的話&#xff0c;可能更需要項目經理&#xff1b;互聯網行業的話&#xff0c;可能更需要產品經理。 項目經理跟產品經理兩個證都挺受市場歡迎的&#xff0c;兩個崗位職責…

關東升老師Python著作推薦(由電子工業出版社出版)

前言&#xff1a;關東升老師簡單介紹 一個在IT領域摸爬滾打20多年的老程序員、軟件架構師、高級培訓講師、IT作家。熟悉Java、Kotlin、Python、iOS、Android、游戲開發、數據庫開發與設計、軟件架構設計等多種IT技術。參與設計和開發北京市公交一卡通百億級大型項目&#xff0c…

釣魚網站域名識別工具dnstwist算法研究

先上一個AI的回答&#xff1a; dnstwist是一種釣魚網站域名識別工具&#xff0c;可幫助用戶識別和檢測可能被惡意使用的域名。它通過生成類似的域名變體來模擬攻擊者可能使用的釣魚域名&#xff0c;并提供了一系列有用的功能和信息。 dnstwist能夠生成一組類似的域名變體&…

HTML常見的列表標簽

目錄 &#x1f367;無序列表&#x1f367;有序列表&#x1f367; 定義列表&#x1f367; 菜單列表 &#x1f367;無序列表 ulli的組合,ul標簽與li標簽之間盡量不要寫標簽或內容 列表可以嵌套多層 type屬性&#xff0c;可以指定序號的類型 可選值&#xff1a;默認值&#xff0c;…

15:00面試,15:06就出來了,問的問題太變態了。。

剛從小廠出來&#xff0c;沒想到在另一家公司我又寄了。 在這家公司上班&#xff0c;每天都要加班&#xff0c;但看在錢給的比較多的份上&#xff0c;也就不太計較了。但萬萬沒想到5月一紙通知&#xff0c;所有人不準加班了&#xff0c;不僅加班費沒有了&#xff0c;薪資還要降…

有病但合理的 ChatGPT 提示語

ChatGPT 面世一年多了&#xff0c;如何讓大模型輸出高質量內容&#xff0c;讓提示詞工程成了一門重要的學科。以下是一些有病但合理的提示詞技巧&#xff0c;大部分經過論文證明&#xff0c;有效提高 ChatGPT 輸出質量&#xff1a; ?1?? Take a deep breath. 深呼吸 ? 作用…

ChatGPT勝過我們人類嗎?

引言 人工智能&#xff08;AI&#xff09;一直是眾多技術進步背后的驅動力&#xff0c;推動我們走向曾經是科幻小說領域的未來。這些進步的核心引出這樣一個深刻的問題&#xff1a;機器能思考嗎&#xff1f;這一問題由英國數學家和計算機科學家艾倫圖靈&#xff08;Alan Turin…

SSL安全證書怎么查看證書類型?

SSL安全證書是一種用于確保互聯網通信安全的協議。它通過加密數據傳輸以保護敏感信息不被竊取或篡改。在瀏覽器中&#xff0c;我們可以輕松查看SSL安全證書的類型。本文將詳細介紹如何查看證書類型&#xff0c;并探討不同類型的SSL證書的用途和特點。 要查看SSL安全證書的類型&…

關于粒子群算法的一些簡單嘗試

粒子群算法核心思想&#xff1a;&#xff08;鳥 粒子&#xff09; &#xff08;1&#xff09;許多的鳥站在不同的地方&#xff1b; &#xff08;2&#xff09;每一只鳥都有自己尋找食物的初始飛行方向、飛行速度&#xff1b; &#xff08;3&#xff09;這些鳥兒每隔一段時間…

ISP-EE(Edge Enhance)

ISP-EE(Edge Enhance) EE模塊在某些ISP主控中叫做sharpness或者sharpen&#xff0c;這些名稱指代的模塊是同一個&#xff0c;不用再糾結。主要就是在YUV域內彌補成像過程中圖像的銳度損失&#xff0c;對邊緣和細節進行加強&#xff0c;從而恢復場景本應具有的自然銳度。 銳度…

Linux基礎指令(2)

今天我們繼續來學我們有關于Linux的指令&#xff0c;今天的指令要比上次多多了。開始我們的學習吧。 man手冊 先來看標題&#xff0c;手冊我們第一時間想到的就是手冊的查閱功能&#xff0c;我們都知道在我們上小學的時候&#xff0c;如果遇到不會的字&#xff0c;我們會通過…

網絡工程師【目錄】

前言 從2023年下半年開始&#xff0c;所有的軟考全面改革&#xff0c;由原來的筆試改為機考&#xff0c;據說難度會有一些增加&#xff0c;望悉知。 報名地址&#xff1a;中國計算機技術職業資格網 歷史報名時間和考試時間&#xff1a;3月份報名&#xff0c;5月底考試&#xf…

互聯網商業史--1.3Q大戰

一.起因 奇虎360與騰訊間的糾葛被業界形象地稱為“3Q大戰”。 這場大戰源于雙方之間的“互掐”。 雙方為了各自利益&#xff0c;從2010年到2014年&#xff0c;上演了一系列互聯網之戰&#xff0c;并走上訴訟之路 騰訊先是推出QQ醫生1.0&#xff0c;隨后推出QQ醫生3.2&#x…