Spring事务和事务传播机制

发布时间:2026/8/9 15:46:11

Spring事务和事务传播机制
(一).回顾事务之前在MySQL阶段就已经介绍过事务的概念了。事务是一组操作的集合是一个不可分割的操作。事务会把所有的操作作为一个整体一起向数据库提交或者撤销操作请求所以这组操作要么同时成功要么同时失败。具体的可以看MySQL专栏关于事务的介绍。(二).Spring中事务的实现1.数据准备这里就拿“用户注册”为示例当用户注册时在日志表中插入一条操作记录(1).SQL脚本-- 创建数据库 DROP DATABASE IF EXISTS trans_test; CREATE DATABASE trans_test DEFAULT CHARACTER SET utf8mb4; -- 用户表 DROP TABLE IF EXISTS user_info; CREATE TABLE user_info ( id INT NOT NULL AUTO_INCREMENT, user_name VARCHAR (128) NOT NULL, password VARCHAR (128) NOT NULL, create_time DATETIME DEFAULT now(), update_time DATETIME DEFAULT now() ON UPDATE now(), PRIMARY KEY (id) ) ENGINE INNODB DEFAULT CHARACTER SET utf8mb4 COMMENT 用户表; -- 操作日志表 DROP TABLE IF EXISTS log_info; CREATE TABLE log_info ( id INT PRIMARY KEY auto_increment, user_name VARCHAR ( 128 ) NOT NULL, op VARCHAR ( 256 ) NOT NULL, create_time DATETIME DEFAULT now(), update_time DATETIME DEFAULT now() ON UPDATE now() ) DEFAULT charset utf8mb4;(2).Controller层代码package org.com.spring_trans.spring_trans_blog.controller; import lombok.extern.slf4j.Slf4j; import org.com.spring_trans.spring_trans_blog.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; Slf4j RestController RequestMapping(/user1) public class UserController1 { Autowired private UserService userService; RequestMapping(/registry) public String registry (String userName,String password){ Integer result userService.registryUser(userName, password); log.info(注册成功); return 注册成功; } }(3).Service层代码package org.com.spring_trans.spring_trans_blog.service; import lombok.extern.slf4j.Slf4j; import org.com.spring_trans.spring_trans_blog.mapper.UserInfoMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; Service Slf4j public class UserService { Autowired private UserInfoMapper userInfoMapper; public Integer registryUser(String userName,String password){ //插入用户信息 return userInfoMapper.insert(userName,password); } }package org.com.spring_trans.spring_trans_blog.service; import lombok.extern.slf4j.Slf4j; import org.com.spring_trans.spring_trans_blog.mapper.LogInfoMapper; import org.com.spring_trans.spring_trans_blog.mapper.UserInfoMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; Service Slf4j public class LogService { Autowired private LogInfoMapper logInfoMapper; public Integer insertLog(String userName,String op){ //记录用户操作 return logInfoMapper.insert(userName,op); } }(3).Mapper层代码package org.com.spring_trans.spring_trans_blog.mapper; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; Mapper public interface UserInfoMapper { Insert(insert into user_info (user_name,password) values (#{userName},#{password})) Integer insert(String userName,String password); }package org.com.spring_trans.spring_trans_blog.mapper; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; Mapper public interface LogInfoMapper { Insert(insert into user_info (user_name,op) values (#{userName},#{op})) Integer insert(String userName,String op); }(4).Model层代码package org.com.spring_trans.spring_trans_blog.model; import lombok.Data; import java.util.Date; Data public class UserInfo { private Integer id; private String userName; private String password; private Date createTime; private Date updateTime; }package org.com.spring_trans.spring_trans_blog.model; import lombok.Data; import java.util.Date; Data public class LogInfo { private Integer id; private String userName; private String op; private Date createTime; private Date updateTime; }2.事务的分类Spring中的事务操作有两种第一种是“编程式事务”需要手动写代码操作事务第二种是“声明式事务”利用注解自动开启和提交事务。(1).编程式事务主要有三个步骤①.开启事务 ②.提交事务 ③.回滚事务具体在代码里呈现当程序运行的时候此时发现是可以成功的同样也可以进行回滚事务可以发现虽然返回的是“注册成功”但是在数据库中并没有记录(2).声明式事务声明式事务使用的是Transactional注解我们只需要在要添加事务的方法上加上Transactional注解就可以实现了不需要手动开启事务和提交事务进入方法时会自动开启事务方法执行完毕后会自动提交事务如果中途发生了没有处理的异常会自动回滚事务可以看到程序正常运行现在我手动添加了一个异常但是并没有进行处理当我再进行测试可以看到后端报错了并且数据库中也没有对应的记录当我对异常进行了捕获此时再进行测试可以看到当我对异常进行了捕获之后事务也是可以正常提交的(三)..Transactional介绍上图是Transactional注解中的属性。这里只介绍里面比较重要的属性1.rollbackForrollbackFor指的是异常回滚属性用于指定能够触发事务回滚的异常类型可以指定多个异常类型Transactional默认旨在遇到运行时异常和Error时才进行回滚非运行时异常不回滚。当我抛出一个IO 输入输出受检异常的时候再进行测试虽然报错了但是事务没有进行回滚数据也插入到了数据库中。如果想要进行设置那么就需要在Transactional中添加相应的属性通过rollbackFor属性来执行出现IOException时事务进行回滚可以发现这次事务就进行了回滚2.isolationisolation指的是事务的隔离级别是为了解决多个事务同时调用一个数据库的问题Spring事务的隔离级别和MySQL事务的隔离级别类似(1).MySQL事务隔离级别MySQL的隔离级别分为四类读未提交读已提交可重复读串行化Ⅰ.读未提交读未提交指的是事务2可以读取到事务1中未提交的数据Ⅱ.读已提交读已提交指的是事务2可以读取到事务1已经提交的数据Ⅲ.可重复读可重复读指的是事务2不会读到事务1对已有数据的修改即使事务1已经提交了也是读不到的。这样也就可以确保同一事务多次查询的结果一致。(快照读)但是也会产生“幻读”(当前读)问题Ⅳ.串行化串行化也称为“序列化”事务的最高隔离级别。它会强制事务排序使其不发生冲突从而解决脏读不可重复读幻读问题。但是会导致执行效率低(2).Spring事务隔离级别Spring事务的隔离级别有5种和MySQL的隔离级别一样在Transactional注解中可以进行设置3.propagationpropagation为“事务传播机制”下面开始详细介绍(1).什么是事务传播机制事务传播机制就是多个方法存在调用关系时事务是如何在这些方法间进行传播的例如现在controller层方法A调用Service层的B方法A方法运行时会开启一个事务B方法本身也有事务此时B方法运行时到底是加入A的事务还是B创建一个新的事务这就涉及到了“事务的传播机制”了“事务的传播机制”是为了解决一个事务在多个节点或者方法中传递的问题(2).事务的传播机制有哪些Spring事务的传播机制有七种(3).传播机制的使用场景Ⅰ.REQUIRED现在三个方法上的事务传播机制我都设置成了REQUIRED当程序运行起来的时候通过日志可以发现自始至终使用的都是一个事务当我在Controller层的方法里面手动加了一个异常后再运行可以看到当发生异常之后并没有进行提交事务而是进行了回滚并释放和关闭了会话因为在Controller层发生了异常Service层的两个方法和Controller层使用的同一个事务所以Service层的两个方法也回滚了Ⅱ.REQUIRES_NEW现在Contoller层的事务传播机制依旧为REQUIRED然后Service层的两个方法的事务传播机制设置为了REQUIRES_NEW当程序运行起来的时候可以看到UserService的事务在增加完数据之后就提交了同样LogSerivce也是可能有人会问Controller层不是还有事务的吗这是因为Controller层的事务并没有执行数据库操作不会生曾SqlSession所以控制台看不到它现在我在LogService层的方法中创建了一个异常现在再进行测试可以看到虽然报错了但是user_info表中是可以插入数据的log_info 表中数据是没有插入成功的。通过日志可以发现在logService抛异常之前UserService中的那个事务已经提交了并没有涉及到LogService这也证实了REQUIRES_NEW级别的传播机制事务和事务之间是互不影响的当我在controller层创建了一个异常可以看到虽然抛出了异常但是抛出异常之前UserService和LogService对应的事务都已经提交了并没有产生影响Ⅲ.NEVER此时我将UserService中的方法的事务传播机制改成了NEVER发现直接报错了因为在controller层是有一个事务的当执行到UserService的时候发现当前存在事务此时就直接报错了。Ⅳ.NESTED此时我将UserService 和 LogService 的事务传播机制都修改成了 NESTED然后开始测试可以发现只有方法执行完成之后最后提交的事务并且是一个事务。当我在LogService中添加一个异常之后再进行测试可以发现事务并没有进行提交而是进行了回滚操作那么测试到这可以发现这个NESTED 看起来和 REQUIRED 没什么区别实则不然下面继续修改代码现在我修改我的代码当产生异常的时候进行捕获然后回滚事务。此时再进行测试可以发现user_info 表数据添加成功log_info表添加失败这就看出NESTED 和 REQUIRED 的区别来了LogService中的事务发生了回滚但是嵌套事务不会回滚到嵌套之前的事务也就是说嵌套事务可以实现部分事务回滚。Ⅴ.NESTED 和 REQUIRED的区别①.如果真个事务全部执行成功则二者的结果是一样的②.如果事务一部分执行成功一部分发生回滚那么REQUIRED加入事务会导致整个事务全部回滚NESTED嵌套事务可以实现局部回滚不会影响上一个方法中执行的结果③.嵌套事务之所以能够实现事物的部分回滚是因为事务中有一个保存点(savepoint)的概念嵌套事务进入之后相当于新建了一个保存点所以回滚时之回滚到当前保存点。④.REQUIRED是加入当前事务中并没有创建事务的保存点因此出现了回滚就是回滚整个事务。Ⅵ.NESTED 和 REQUIRES_NEW的区别①.NESTED是同一个事务依靠保存点分段REQUIRES_NEW是两个独立的事务②.NETED是如果当前存在事务则创建一个事务作为当前事务的嵌套事务依托外层主事务的保存点实现③.REQUIRES_NEW是创建一个新的事务如果当前存在事务则将当前事务挂起无论外部方法是否开启事务REQUIRES_NEW修饰的内部方法都会开启自己的事务且开启的事务相互独立互不影响。④.对于NESTED来说如果内部发生异常并且进行了捕获此时只会进行局部回滚回滚到嵌套的保存点外层捕获异常可以继续往下执行如果外部发生异常则直接全部回滚所有嵌套的子事务强制一起回滚⑤.REQUIRES_NEW来说外部事务回滚不影响内层事务如果内部报错回滚那么外部捕获异常之后依然可以正常提交

相关新闻

VisualCppRedist AIO:终极Windows运行库修复工具,3分钟解决系统兼容性问题

VisualCppRedist AIO:终极Windows运行库修复工具,3分钟解决系统兼容性问题

2026/8/9 15:36:06

VisualCppRedist AIO:终极Windows运行库修复工具,3分钟解决系统兼容性问题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 面对Windows系…

AI的「内心」真的存在吗?——论内在透明性的存在论差异-龍德明宇

AI的「内心」真的存在吗?——论内在透明性的存在论差异-龍德明宇

2026/8/9 15:36:06

AI的「内心」真的存在吗?——论内在透明性的存在论差异 作者:龍德明宇 核心结论 你有没有这种感觉:认识一个人,起初觉得他很nice,但相处久了总觉得哪里不对——笑容有点假,说话总在试探底线。你想解释这种「…

Unity从零构建开源飞行引擎:模块化架构与空气动力学实现

Unity从零构建开源飞行引擎:模块化架构与空气动力学实现

2026/8/9 15:36:06

1. 项目概述:为什么要在Unity里从零造一个飞行引擎?如果你是一个对飞行模拟、游戏开发或者无人机仿真感兴趣的开发者,看到“从零开始构建开源飞行引擎”这个标题,可能会觉得这又是一个庞大得吓人的工程。确实,市面上有…

制造业数据治理框架与实施路径详解

制造业数据治理框架与实施路径详解

2026/8/9 16:56:14

1. 制造业数据治理全景解析 作为从业十五年的数据治理专家,我完整参与了某汽车零部件制造集团的数据治理项目。这个投资超千万的项目历时两年半,最终实现了全业务链条数据质量提升47%,报表生成效率提升62%。今天以这个真实案例为蓝本&#xf…

AI如何10分钟生成专业PPT:核心技术解析与实践指南

AI如何10分钟生成专业PPT:核心技术解析与实践指南

2026/8/9 16:56:14

1. 项目概述:AI如何重塑PPT制作流程 作为一名常年被PPT折磨的咨询顾问,我至今记得第一次用AI工具生成演示文稿时的震撼。那天下午4点接到客户需求,要求第二天上午9点交付一份30页的行业分析报告。按照传统工作流程,光是数据收集和…

深入解析Nginx高并发架构:从事件驱动到内存池的设计精髓

深入解析Nginx高并发架构:从事件驱动到内存池的设计精髓

2026/8/9 16:56:14

这次我们来看 Nginx 的核心架构。它不是教你配置一个 location 规则,而是直接拆开 Nginx 的“引擎盖”,看看它处理海量并发请求时,内部到底是怎么转的。为什么它能轻松应对 C10K 甚至 C100K 问题?为什么在高并发场景下&#xff…

Unity动画混合树:从原理到实战,打造平滑角色动画

Unity动画混合树:从原理到实战,打造平滑角色动画

2026/8/9 16:56:14

1. 项目概述:为什么动画混合是游戏角色的灵魂在Unity引擎里做角色动画,新手最容易犯的错误就是把动画当成一个个独立的“视频片段”来播放。比如,角色从静止到跑步,你可能会做一个“起跑”动画,然后立刻切换到“跑步循…

XCOM 2模组管理器终极指南:如何用AML启动器告别模组冲突烦恼

XCOM 2模组管理器终极指南:如何用AML启动器告别模组冲突烦恼

2026/8/9 16:56:14

XCOM 2模组管理器终极指南:如何用AML启动器告别模组冲突烦恼 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mir…

陶瓷散热片在嵌入式设备中的应用:原理、选型与实战指南

陶瓷散热片在嵌入式设备中的应用:原理、选型与实战指南

2026/8/9 16:46:14

陶瓷散热片:路由器、监控、商显、安卓主板的“冷静”革命 如果你拆开过近两年的路由器、网络摄像头、广告机或者安卓工控主板,可能会发现一个变化:那些熟悉的铝制或铜制散热片旁边,多了一些白色或米黄色的“小瓷片”。这不是装饰&…

比较好的亚太EMBA,问了6位校友师资差别真的挺大

比较好的亚太EMBA,问了6位校友师资差别真的挺大

2026/8/9 0:05:25

比较好的亚太EMBA核心差异先看什么?对于希望兼顾工作与系统管理能力提升的亚太区高管而言,筛选匹配度高的EMBA项目时,师资配置是决定学习体验与实际收获的核心要素之一。我们结合3-4个公开信息透明、办学历史较长的亚太区主流EMBA项目特点&am…

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

2026/8/9 0:05:25

备考海外游学的亚洲EMBA面试,核心要围绕项目国际化设计逻辑、个人跨文化管理经验匹配度两个维度准备,避免把游学模块等同于普通旅游参访的认知偏差。不少备考者花3个月对比6份资料,却容易忽略面试官对“国际视野落地能力”的考察——比如香港…

比较好的国内EMBA,问了二十位校友聊透人脉价值

比较好的国内EMBA,问了二十位校友聊透人脉价值

2026/8/9 0:05:25

比较好的国内EMBA核心差异体现在哪些方面?比较好的国内EMBA的核心长期价值,很大程度上依托于校友网络的连接质量与资源生态的活跃度,这也是不少高管在择校时优先考量的因素。我们结合3-4个市场关注度较高的项目公开信息,从课程、师…

比较好的亚太EMBA,问了6位校友师资差别真的挺大

比较好的亚太EMBA,问了6位校友师资差别真的挺大

2026/8/9 0:05:25

比较好的亚太EMBA核心差异先看什么?对于希望兼顾工作与系统管理能力提升的亚太区高管而言,筛选匹配度高的EMBA项目时,师资配置是决定学习体验与实际收获的核心要素之一。我们结合3-4个公开信息透明、办学历史较长的亚太区主流EMBA项目特点&am…

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

2026/8/9 0:05:25

备考海外游学的亚洲EMBA面试,核心要围绕项目国际化设计逻辑、个人跨文化管理经验匹配度两个维度准备,避免把游学模块等同于普通旅游参访的认知偏差。不少备考者花3个月对比6份资料,却容易忽略面试官对“国际视野落地能力”的考察——比如香港…

比较好的国内EMBA,问了二十位校友聊透人脉价值

比较好的国内EMBA,问了二十位校友聊透人脉价值

2026/8/9 0:05:25

比较好的国内EMBA核心差异体现在哪些方面?比较好的国内EMBA的核心长期价值,很大程度上依托于校友网络的连接质量与资源生态的活跃度,这也是不少高管在择校时优先考量的因素。我们结合3-4个市场关注度较高的项目公开信息,从课程、师…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/8 5:07:31

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/9 13:42:46

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/8 2:30:15

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…