【Spring Boot】Spring 事务探秘:核心机制与应用场景解析

Springboot 跟着我了解下 事务 @Transactional 默认方式 Propagation.REQUIRED 在平常的项目里面,最常看到的就是使用注解@Transactional 去操作事务。 如果稍微对spring事物有过了解的,会知道关于事物传播机制,存在6种, 也就是: 同样可以在注解@Transactional里面看到, 默认配置了的是Propagation.REQUIRED (文章的主角) 而在这里也是其实告诉咱们,就算使用注解也是可以指定不同的事物机制: 为什么该篇文章,6种,我只介绍一种呢?而且是介绍的是PROPAGATION_REQUIRED 呢?... 阅读详情

前言

???本期讲解关于spring 事务介绍~~~

??感兴趣的小伙伴看一看小编主页:-优快云博客

?? 你的点赞就是小编不断更新的最大动力

??那么废话不多说直接开整吧~~

目录

???1.事务

??1.1什么是事务

??1.2为什么需要事务

??1.3操作事务

???2.Spring事务

??2.1编程式事务

??2.2声明式事务

1.异常捕获

2.异常捕获再次抛出

3.编译时异常

4.运行时异常

5@transaction属性

6.@transaction总结

???3.总结

**??**1.事务

??1.1什么是事务

事务是组操作的集合, 是个不可分割的操作.
事务会把所有的操作作为个整体, 起向数据库提交或者是撤销操作请求. 所以这组操作要么同时成功, 要么同时失败

??1.2为什么需要事务

假如有以下场景,若在存钱的过程中,A账户减少了100元,本应该就是在B账户中多出100元,但是

如果没有事务,第步执成功了, 第步执失败了, 那么A 账的100 元就平故消失了. 如果使事务就可以解决这个问题, 让这组操作要么起成功, 要么起失败

就可以解决上述的问题了;

??1.3操作事务

在数据库中操作事务有以下几个步骤:

1. 开启事start transaction/ begin (组操作前开启事务)

2. 提交事务: commit (这组操作全部成功, 提交事务)

3. 回滚事务: rollback (这组操作中间任何个操作出现异常, 回滚事务)

当然这是在MySQL阶段学习的几个事务操作步骤,但是spring也是有事务的操作的,那么我们接着往下面看看~~~

**??**2.Spring事务

MySQL对于事务进行了实现,Spring对事务也是进行了实现,具体有两种实现方式:

Spring 中的事务操作分为两类:

1. 编程式事务(动写代码操作事务)
2. 声明式事务(利注解动开启和提交事务)

首先,要进行之前mybatis的数据库操作,这里小编就不在进行演示了;

??2.1编程式事务

SpringBoot 内置了两个对象:
1. DataSourceTransactionManager 事务管理器. 来获取事务(开启事务), 提交或回滚事务
2. 的TransactionDefinition 是事务的属性, 在获取事务的时候需要将
TransactionDefinition 传递进去从获得个事务 TransactionStatus

具体的代码如下所示:

@RestController
@RequestMapping("/user")
public class UserController {
    //手动改开启事务
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

    @Autowired
    private UserService userService;

    @RequestMapping("/regist")
    public boolean regist(String userName,String password){

        //开启事务
        TransactionStatus transactionStatus=
                dataSourceTransactionManager.getTransaction(transactionDefinition);
        //操作数据库
        userService.registUser(userName,password);
        //提交事务
        dataSourceTransactionManager.commit(transactionStatus);

        //回滚事务
        dataSourceTransactionManager.rollback(transactionStatus);
        return true;
    }
}

解释:

注意这里要注入事务管理器对象,以及事务属性对象,这两个相当于是获取事务的状态,然后通过事务管理器通过提交或者回滚来操作我们的事务状态;

操作完数据库后,才进行事务的对应的处理哦~~~

具体的日志打印如下:

此时就是进行了事务的回滚,如果进行了事务的提交,那么就会存在一个commit单词的日志;

这里就是进行了事务的提交;

当然这里小编演示的时候,需要注释掉其中一个事务的操作,因为不可能事务提交又进行了回滚是吧~~~

??2.2声明式事务

这里的操作分为两步,主要式通过注解进行事务的自动开启:

第一步:添加依赖

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-tx</artifactId>
</dependency>

但是这里的依赖添加,这里小编添加了lombok,spring web,mybatis farmwork,mysql driver,并没有引入这里的依赖;

第二步:添加注解

在需要事务的法上添加 @Transactional 注解就可以实现了. 需动开启事务和提交事
务, 进法时动开启事务, 法执完会动提交事务, 如果中途发了没有处理的异常会动
回滚事务

代码如下所示:

@RestController
@RequestMapping("/trans")
public class TransController {
    @Autowired
    private UserService userService;
   
    @Transactional 
    @RequestMapping("t1")
    public Boolean register(String userName, String password){
        Integer result = userService.registUser(userName, password);
        System.out.println("插入用户表, result: "+ result);
     
        return true;
    }

当然,如果这里的存在异常情况下时,代码如下所示:

@Transactional
    @RequestMapping("t1")
    public Boolean register(String userName, String password){
        Integer result = userService.registUser(userName, password);
        System.out.println("插入用户表, result: "+ result);
        
        int a = 10/0;
       
        return true;
    }

那么此时就会发生回滚,数据库就不会插入对应的数据;

但是对于所有发生了异常,此时事务都会进行回滚吗?当然不是,还要分为以下情况

1.异常捕获

当我们进行异常捕获后,代码如下所示

@RestController
@RequestMapping("/trans")
public class TransController {
    @Autowired
    private UserService userService;
    /**
    程序异常,捕获并处理,这里结果就是提交
     */
    @Transactional
    @RequestMapping("t1")
    public Boolean register(String userName, String password){
        Integer result = userService.registUser(userName, password);
        System.out.println("插入用户表, result: "+ result);
        try {
            int a = 10/0;
        }catch (Exception e){
            //打印堆栈信息
            e.printStackTrace();
        }
        return true;
    }

解释:

这里就是通过try catch后进行堆栈信息的打印,所以最后就会进行事务的提交

(事务的提交与否,主要查看日志,是否存在commit的单词,或者去观察在数据库中数据是否进行了插入的操作)

2.异常捕获再次抛出

代码如下所示:

 /**
    捕获异常之后,没有处理,直接再次抛出,回滚
     */
    @Transactional
    @RequestMapping("t2")
    public Boolean register1(String userName, String password){
        Integer result = userService.registUser(userName, password);
        System.out.println("插入用户表, result: "+ result);
        try {
            int a = 10/0;
        }catch (Exception e){
            throw e;
        }
        return true;
    }

解释:

在捕获到这里的算数异常后,再次把异常进行抛出,那么此时就相当于是没有进行捕获的,那么事务就会进行回滚,并且这里还可以进行手动回滚;

在捕获异常后,添加:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

此时就会进行手动的回滚操作;

3.编译时异常

代码如下所示:

/**
     *  事务提交
     */
    @Transactional
    @RequestMapping("/t4")
    public Boolean r4(String userName, String password) throws IOException {
        Integer result = userService.registUser(userName, password);
        System.out.println("插入用户表, result: "+ result);
        if (true){
            throw new IOException();//为编译时异常
        }

        return true;
    }

解释:

在事务的提交中,只有运行时异常,以及rerror会触发回滚,但是在这里的编译时异常是不可以回滚的(大致的可以理解为就是编译时异常有明显的报错,希望我们自己改正,这里事务就不管了)

当然还有一种情况

/**
     *  事务回滚
     */
    @Transactional
    @SneakyThrows
    @RequestMapping("/t5")
    public Boolean r5(String userName, String password)  {
        Integer result = userService.registUser(userName, password);
        System.out.println("插入用户表, result: "+ result);
        if (true){
            throw new IOException();
        }
        //在反编译中这里会捕获异常,并再次抛出
        return true;
    }

这里的事务结果就是回滚,为什么呢?这里添加了注解@SneakyThrows,我们在反编译文件中可以看到这里还进行了异常的捕获,但是没有处理,直接把异常抛出了,所以这里就是第二种情况

4.运行时异常

代码如下所示:

/**
     *  事务回滚
     */
    @Transactional
    @RequestMapping("/t6")
    public Boolean r6(String userName, String password)  {
        Integer result = userService.registUser(userName, password);
        System.out.println("插入用户表, result: "+ result);
        if (true){
            //这里抛出的就是运行时异常,需要进行回滚
            throw new RuntimeException();
        }

        return true;
    }

这里的的事务那么就是直接回滚了,小编不再进行过多的赘述;

5@transaction属性

1. rollbackFor: 异常回滚属性. 指定能够触发事务回滚的异常类型. 可以指定多个异常类型

2. Isolation: 事务的隔离级别. 默认值为 Isolation.DEFAULT

3. propagation: 事务的传播机制. 默认值为 Propagation.REQUIRED

注意:

@Transactional 默认只在遇到运时异常和Error时才会回滚, 运时异常不回滚. 即
Exception的类中, 除了RuntimeException及其类其他的会不进行回滚

但是我们可以指定这里rollbackfor为所有异常类型,所以对于所有的异常,此时都会进行回滚的操作;代码如下所示:

@Transactional(rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
    //设置所有回滚异常类型
    @RequestMapping("/r7")
    public Boolean r7(String userName, String password) throws IOException {
        Integer result = userService.registUser(userName, password);
        System.out.println("插入用户表, result: "+ result);
        if (true){
            throw new IOException();
        }

        return true;
    }
6.@transaction总结

@Transactional 可以来修饰法或类:
修饰法时: 只有修饰public 法时才效(修饰其他法时不会报错, 也不效)[推荐]
修饰类时: 对 @Transactional 修饰的类中所有的 public 法都效.
法/类被 @Transactional 注解修饰时, 在标法执开始之前, 会动开启事务, 法执结束
之后, 动提交事务.

如果在法执过程中, 出现异常, 且异常未被捕获, 就进事务回滚操作.
如果异常被程序捕获, 法就被认为是成功执, 依然会提交事务,但是捕获后重新抛出,就会回滚,若为运行时异常,那么也会进行回滚,但是编译时异常在不添加SneakyThrow时为提交;

**??**3.总结

本期主要讲解了关于事务,以及Spring事务的知识,对于Spring 事务的两种方式,小编都进行了代码的演示;

???~~~~最后希望与诸君共勉,共同进步!!!


???以上就是本期内容了, 感兴趣的话,就关注小编吧。

???期待你的关注~~~

深入探讨JavaWeb之Spring Boot事务管理:进阶案例与实践解析 在Java Web的开发过程中,事务管理无疑是保障数据一致性和操作原子性的重要一环。上期我们深入探讨了Spring Boot中基本的事务管理应用,涵盖了事务的基础配置、常用注解以及事务的基本运作原理。这些知识点构成了我们在Java Web开发中实现事务管理的基础,但在实际应用中,仅靠这些基本配置往往无法满足复杂业务的需求。本期将深入探索更为进阶的Spring Boot事务管理应用,通过具体案例解析事务的高级配置与应用场景,进一步帮助开发者在面对复杂业务逻辑时能更好地驾驭事务,确保数据安全性和系统稳定性。 阅读详情

相关推荐

Kerberos基础及KDC服务(理论知识)

kerberos基础理论讲解+KDC服务

Siobhan_Mxin的博客 9712

Spring(SpringBoot)--事务传播机制--应用/实例/详解

Spring(SpringBoot)--事务传播机制--应用/实例/详解

向上的"狼"的博客 929

VSCode + ESP-IDF 项目搭建及配置

VSCode 搭建 ESP-IDF 开发环境

weixin_51358957的博客 2万+

SpringBoot事务传播机制

Spring事务传播机制

weixin_61518137的博客 2371

Android开发者必看:F2FS文件系统如何优化你的手机存储性能(附实测数据对比)

本文深入解析了F2FS文件系统如何针对闪存特性优化Android设备存储性能。通过对比ext4,F2FS采用追加写和冷热数据分离策略,将随机写转化为顺序写,显著提升写入速度并减少GC卡顿。实测数据显示,其在随机写入和SQLite事务等场景下性能提升显著,为开发者提供了优化应用IO性能的关键思路。

weixin_29248313的博客 325

【LLM】ms-Swift框架下SFT与GRPO协同优化的高效训练策略

本文深入探讨了ms-Swift框架下监督微调(SFT)与群组相对策略优化(GRPO)的协同训练策略,提升大型语言模型(LLM)的性能与效率。通过创新的架构设计和两阶段训练流程,结合GRPO的群组奖励估计与动态基线调整技术,显著优化了数学推理等任务的准确率。文章还分享了计算资源高效利用和参数调优的实战经验,为LLM训练提供了实用指导。

green的博客 994

Javaweb之SpringBootWeb案例之propagation属性案例演示的详细解析

那此时,DeptServiceImpl中的delete方法运行时,会开启一个事务。当调用 deptLogService.insert(deptLog) 时,也会创建一个新的事务,那此时,当insert方法运行完毕之后,事务就已经提交了。即使外部的事务出现异常,内部已经提交的事务,也不会回滚了,因为是两个独立的事务。此时:delete和insert操作使用了同一个事务,同一个事务中的多个操作,要么同时成功,要么同时失败,所以当异常发生时进行事务回滚,就会回滚delete和insert操作。

qq_69748833的博客 1370

告别偏移地址!用C# S7PLUS驱动读写西门子S7-1500符号地址(TIA Portal V17+环境配置)

本文详细介绍了如何在TIA Portal V17+环境中使用C# S7PLUS驱动读写西门子S7-1500 PLC的符号地址,告别传统的偏移地址方式。通过配置OpenSSL、集成S7PLUS驱动库,以及实战案例展示符号地址的读写方法,显著提升代码可读性和维护效率。文章还涵盖了环境准备、高级配置及常见问题解决方案,助力工业自动化开发者实现更高效的PLC通讯。

weixin_28720767的博客 316

SpringBoot事务管理

场景:Excel导入人口信息。需要先删除重复的,然后循环插入一条条信息(due to 许多原因,整个流程最开始是放在一个方法里的)。由于导入的一条数据涉及多个表格的查询和插入,会存在需要回滚的情况。e.g. A数据先插入,B数据后插入。由于B数据插入错误,A也必须回滚到插入前的状态。但一直没有成功。刚好对spring boot的事务回滚不是很了解,现在记录下学习的情况。

InnnnnnnnnnNoVation的博客 382

深度学习简介(框架)

深度学习是一种基于人工神经网络的机器学习方法,它通过模拟人脑的工作原理来解决复杂的数据模式识别问题。这种方法在图像识别、语音识别、自然语言处理等领域取得了显著的进展。深度学习是机器学习的一个子领域,它基于人工神经网络的学习算法,特别是那些具有多层(深层)结构的网络。这些深度神经网络能够学习数据的高级特征和模式。深度学习作为人工智能的关键驱动技术,已经在多个领域展现出其强大的能力。随着研究的深入和技术的发展,深度学习将继续推动人工智能的边界向前发展。

2301_77539454的博客 5351

21、深入了解SELinux安全系统与/proc文件系统

本文深入探讨了SELinux安全系统与/proc文件系统的原理及实际应用。详细介绍了SELinux的安全上下文、域转换、运行模式、角色管理以及策略查看工具seinfo的使用;同时解析了/proc文件系统的结构与功能,涵盖进程信息查看、系统资源监控及性能优化方法。结合SELinux与/proc的协同应用,提供了系统问题排查流程与安全管理最佳实践,帮助用户提升Linux系统的安全性与稳定性。

ik678901234的博客 61

Spring Boot 事务管理深度解析

保持事务简短: 长事务会长时间持有数据库锁和连接资源,严重影响系统并发性能,并增加死锁的风险。应将事务的范围严格限制在必要的数据库操作上。事务边界在服务层 (Service Layer): 通常,事务边界应该定义在服务层的方法上,而不是控制器层或 DAO 层。服务层封装了完整的业务逻辑单元,是定义事务边界最自然的地方。避免在事务中包含耗时操作: 不应在事务方法中执行如 RPC 调用、文件 I/O、复杂的内存计算等非数据库相关的耗时操作。

EscaRC的博客 1414

华为的LTC(Lead to Cash,从线索到现金)流程是其销售管理体系的核心,覆盖了从发现销售线索到最终收回现金的全过程,强调端到端的业务贯通和以客户为中心的运营理念

华为LTC流程是覆盖销售全周期的管理体系,包含四大阶段:线索转机会(LTO)、机会转订单(OTO)、订单转交付(OTD)、交付转现金(DTC)。其核心采用"铁三角"团队模式(AR/SR/FR协作),通过多部门联合评审把控关键节点,实现端到端业务贯通。该流程与IPD、MTL、ITR等体系高效协同,结合iSales平台实现数字化管理,有效提升销售效率、客户满意度和资金回笼速度。

金牌架构师 1721

深入解析 Spring Boot 中的 SPI 机制与应用

SPI(Service Provider Interface,服务提供者接口)是 Java 提供的一种机制,允许框架或应用程序根据需要动态加载服务的实现。SPI 通过接口定义服务行为,并允许多个服务提供者在运行时为该接口提供不同的实现。这种机制为系统的模块化和可扩展性提供了灵活性,使得服务的具体实现可以在不修改客户端代码的情况下进行替换。简单来说,SPI 是一种设计模式,允许服务的具体实现由外部提供,这种灵活性使得应用程序可以更好地应对变化,并支持动态扩展。在 Java 中,SPI 机制依赖于。

hello.reader 3504

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Spring Boot 注解:深度解析与应用场景

Spring Boot 注解为开发者提供了一种简洁、高效的方式来构建应用程序,涵盖了从应用启动、组件管理、依赖注入、Web 请求处理到事务管理等多个方面。通过深入理解这些注解的作用、原理和常用场景,开发者能够更加熟练地运用 Spring Boot 框架,提高开发效率,构建出高质量、可维护的应用程序。随着对 Spring Boot 的不断深入学习和实践,开发者还会遇到更多丰富且强大的注解,进一步提升开发体验和应用性能。

lijingxiaov5的博客 1266

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

RocketMQ事务消息:从Spring Boot实战到底层原理深度解析

事务设计原则单个事务消息体 < 1MB本地事务执行时间 < 10秒事务日志保留至少7天推荐工具链RocketMQ Dashboard:实时监控事务状态Arthas:在线诊断事务问题Prometheus+Grafana:构建监控大盘演进方向事务消息+Saga模式:处理长事务场景事务消息+CDC:实现分布式数据同步Serverless事务方案:基于事件驱动架构。

danny-IT技术博客 1168

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Spring框架核心知识深度解析

创建模块编写自动配置类:@Configuration@Bean添加文件@Override// 其他方法实现...// 注册自定义作用域。

2301_79730192的博客 977

Spring框架核心机制:IoC、AOP与事务管理深度解析

IoC(控制反转)和AOP(面向切面编程)是Spring框架的两大核心技术支柱。IoC容器通过依赖注入管理对象生命周期,其核心BeanFactory采用三级缓存机制解决循环依赖问题。AOP基于动态代理实现,支持方法拦截和增强,在日志记录、事务管理等场景发挥关键作用。Spring的事务管理建立在AOP基础上,通过@Transactional注解实现声明式事务控制。这些机制共同构成了Java企业级开发的基础架构,广泛应用于微服务、分布式系统等场景。理解Spring 5的CGLIB代理优化和Bean作用域选择对性

weixin_30251829的博客 640

Spring Boot入门实战与核心机制解析

本文介绍了Spring Boot的核心理念及其在Java后端开发中的应用。通过“约定优于配置”,Spring Boot简化了开发,提供起步依赖、自动配置等特性。文章以“HelloWorld”Web应用为例,展示了项目创建、核心注解使用及自动配置原理,并提及Actuator监控功能。Spring Boot降低了开发门槛,助力快速构建高质量Java应用。

cylz007的博客 1170
上一篇: 【Spring Boot】Spring Boot解决循环依赖
下一篇: 国产之光DeepSeek架构理解与应用分析
AIGC镜像空间
博客等级 码龄5年 4万+粉丝 689原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值