Spring事务与事务传播机制教程|从入门到实战,一篇吃透@Transactional

news2026/4/11 23:36:57
—JavaEE专栏—Spring事务与事务传播机制教程从入门到实战一篇吃透Transactional大家好我是一名后端开发今天带来一篇Spring事务传播机制的硬核实战博客包含原理代码图文面试高频完整实战案例看完彻底搞定Spring事务再也不怕数据不一致 前言为什么要学Spring事务保证原子性要么全成功要么全回滚解决数据一致性转账、下单、注册等核心业务必备面试必问事务隔离级别、传播机制、Transactional失效场景本文基于SpringBoot从基础事务操作 → 编程式/声明式事务 → 隔离级别 →7大传播机制附带8个真实业务事务案例小白也能直接运行复现一、数据库事务基础回顾事务就是一组不可分割的操作遵循ACID原则原子性全部成功 or 全部失败一致性执行前后数据合法隔离性多事务互不干扰持久性提交后永久生效MySQL原生事务操作-- 开启事务STARTTRANSACTION;/BEGIN;-- 业务SQLINSERTINTOuser_info...;-- 提交/回滚COMMIT;ROLLBACK;缺点代码冗余、侵入性强Spring帮我们自动化二、Spring事务两种实现方式Spring提供编程式和声明式两种事务开发中99%用声明式。1. 编程式事务手动控制事务开启、提交、回滚代码繁琐适合特殊场景。核心对象DataSourceTransactionManager事务管理器TransactionDefinition事务属性TransactionStatus事务状态RestControllerRequestMapping(/user)publicclassUserController{AutowiredprivateDataSourceTransactionManagertransactionManager;AutowiredprivateTransactionDefinitiontransactionDefinition;AutowiredprivateUserServiceuserService;RequestMapping(/registry)publicStringregistry(Stringname,Stringpassword){// 1.开启事务TransactionStatusstatustransactionManager.getTransaction(transactionDefinition);try{// 2.执行业务userService.registryUser(name,password);// 3.提交transactionManager.commit(status);return成功;}catch(Exceptione){// 4.异常回滚transactionManager.rollback(status);return失败;}}}2. 声明式事务重点Transactional只需一个注解自动开启、提交、回滚基于AOP实现无侵入性两步使用引入事务依赖SpringBoot已自动集成dependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactId/dependency方法/类上添加TransactionalServicepublicclassUserService{AutowiredprivateUserInfoMapperuserInfoMapper;// 声明事务TransactionalpublicvoidregistryUser(Stringname,Stringpassword){userInfoMapper.insert(name,password);}}✨ Transactional 核心规则修饰public方法*才生效方法正常执行自动提交抛出未捕获异常自动回滚异常被捕获→ 不回滚三、Transactional 三大核心属性1. rollbackFor指定回滚异常默认只回滚RuntimeException Error编译期异常如IOException不回滚// 所有异常都回滚推荐配置Transactional(rollbackForException.class)2. isolation事务隔离级别Spring支持5种隔离级别对应MySQL4种默认级别含义解决问题DEFAULT跟随数据库默认-READ_UNCOMMITTED读未提交脏读READ_COMMITTED读已提交脏读REPEATABLE_READ可重复读不可重复读SERIALIZABLE串行化脏读、不可重复读、幻读使用Transactional(isolationIsolation.READ_COMMITTED)3. propagation事务传播机制多个事务方法互相调用时事务如何传递Spring定义7种传播机制重点掌握REQUIRED、REQUIRES_NEW、NESTED【实战必看】8个Spring事务真实案例事务提交、回滚、异常捕获、手动回滚、编译异常回滚等所有高频场景可直接测试的Controller接口完整Controller代码packagecn.overthinker.trans.controller;importcn.overthinker.trans.entity.UserInfo;importcn.overthinker.trans.service.UserService;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.transaction.annotation.Isolation;importorg.springframework.transaction.annotation.Transactional;importorg.springframework.transaction.interceptor.TransactionAspectSupport;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importjava.io.IOException;Slf4jRestControllerRequestMapping(/trans)publicclassTransController{AutowiredprivateUserServiceuserService;/** * 1. 正常事务提交无异常 → 数据入库成功 */TransactionalRequestMapping(/registry)publicStringregistryUser(UserInfouserInfo){//用户注册userService.insertUser(userInfo);return用户注册成功事务已提交;}/** * 2. 抛出未捕获异常 → 事务自动回滚 * 结果数据不会插入数据库 */TransactionalRequestMapping(/r2)publicStringr2(UserInfouserInfo){//用户注册IntegerresultuserService.insertUser(userInfo);log.info(数据插入成功影响行数result);// 主动抛运行时异常inta10/0;return用户注册成功;}/** * 3. 异常被try-catch捕获 → 事务【不会回滚】 * 结果数据成功入库经典坑点 */TransactionalRequestMapping(/r3)publicStringr3(UserInfouserInfo){//用户注册IntegerresultuserService.insertUser(userInfo);log.info(数据插入成功影响行数result);try{inta10/0;}catch(Exceptione){log.error(程序发生异常被捕获事务不回滚);}return用户注册成功数据已入库;}/** * 4. 捕获异常后重新抛出 → 事务【正常回滚】 * 结果数据不会入库 */TransactionalRequestMapping(/r4)publicStringr4(UserInfouserInfo){//用户注册IntegerresultuserService.insertUser(userInfo);log.info(数据插入成功影响行数result);try{inta10/0;}catch(Exceptione){log.error(程序发生异常被捕获重新抛出异常);throwe;}return用户注册成功;}/** * 5. 捕获异常 手动回滚 → 事务【回滚】 * 结果数据不会入库接口正常返回 */TransactionalRequestMapping(/r5)publicStringr5(UserInfouserInfo){//用户注册IntegerresultuserService.insertUser(userInfo);log.info(数据插入成功影响行数result);try{inta10/0;}catch(Exceptione){log.error(程序发生异常被捕获手动回滚事务);// 手动触发事务回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return用户注册失败事务已手动回滚;}/** * 6. 抛出编译期异常(IOException) → 事务【不回滚】 * 默认规则只回滚 RuntimeException/Error */TransactionalRequestMapping(/r6)publicStringr6(UserInfouserInfo)throwsIOException{//用户注册IntegerresultuserService.insertUser(userInfo);log.info(数据插入成功影响行数result);if(true){// 编译期异常默认不回滚thrownewIOException();}return用户注册成功IO异常未回滚;}/** * 7. 配置 rollbackForException.class → 所有异常都回滚 * 结果IOException 也会触发回滚 */Transactional(rollbackForException.class,isolationIsolation.READ_COMMITTED)RequestMapping(/r7)publicStringr7(UserInfouserInfo)throwsIOException{//用户注册IntegerresultuserService.insertUser(userInfo);log.info(数据插入成功影响行数result);if(true){thrownewIOException();}return用户注册成功IO异常已回滚;}} 案例效果总结接口事务表现核心结论/trans/registry正常提交无异常自动提交/trans/r2自动回滚运行时异常自动回滚/trans/r3不回滚异常被catch事务失效大坑/trans/r4自动回滚捕获后重新抛出生效/trans/r5手动回滚手动控制事务灵活安全/trans/r6不回滚默认不回滚编译期异常/trans/r7自动回滚配置rollbackFor后全异常回滚⚠️ Transactional 常见失效场景非public方法→ 不生效异常被try-catch吃掉→ 不回滚未指定rollbackFor→ 编译异常不回滚同类方法内部调用→ AOP不生效数据库引擎不支持事务如MyISAM四、7大事务传播机制详解图文代码先统一场景用户注册 记录日志两个带事务的方法互相调用。1. REQUIRED默认值 ✅ 最常用有事务加入无事务新建Transactional(propagationPropagation.REQUIRED)内外共用同一个事务一方异常 →全部回滚适用常规业务增删改演示日志方法抛异常 → 用户数据也回滚2. REQUIRES_NEW独立事务 ✅ 高频无论如何都新建事务挂起外层事务Transactional(propagationPropagation.REQUIRES_NEW)内外完全独立日志异常 → 不影响用户注册适用日志、审计、消息发送必须独立成功演示日志失败 → 用户依然注册成功3. NESTED嵌套事务 ✅ 高级有事务则嵌套Savepoint无则同REQUIREDTransactional(propagationPropagation.NESTED)子事务可单独回滚不影响父事务父事务回滚 → 子事务必回滚依赖数据库Savepoint4. SUPPORTS有事务就加无事务非事务运行适用查询操作5. MANDATORY必须有事务无事务直接抛异常适用强制运行在事务内的核心逻辑6. NOT_SUPPORTED非事务运行有事务也挂起适用不需要事务的操作7. NEVER禁止事务有事务抛异常适用明确不能在事务中运行的方法 传播机制核心对比表类型外层有事务外层无事务核心特点场景REQUIRED加入新建共用事务通用业务REQUIRES_NEW新建并挂起新建独立事务日志NESTED嵌套子事务新建局部回滚复杂批量SUPPORTS加入非事务灵活查询MANDATORY加入抛异常强制事务核心逻辑NOT_SUPPORTED挂起非事务无事务非核心操作NEVER抛异常非事务禁止事务安全方法七、总结Spring事务编程式手动声明式Transactional三大属性rollbackFor、isolation、propagation7大传播机制重点REQUIRED、REQUIRES_NEW、NESTED实战8大案例覆盖所有事务坑点直接复制测试开发规范增删改用REQUIRED日志用REQUIRES_NEW

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2507760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…