Spring事务(事务的实现、隔离级别、传播机制)(上)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: Spring事务(事务的实现、隔离级别、传播机制)(上)

一、事务的定义和意义事务的定义


事务的定义

将⼀组操作封装成⼀个执⾏单元(封装到⼀起),要么全部成功,要么全部失败。

简单来说:事务诞生的目的就是为了把若干个独立的操作给打包成一个整体。



我们需要注意的是: Spring 的事务 相比于 MySQL 中的事务,要复杂一些!


MySQL 的事务 无非就是 事务可以并发执行,需要考虑隔离性的问题。

但是!MySQL 的事务 非常单纯!

它不会说出现事务嵌套的问题。

比如:事务 A 嵌套了 事务 B,事务 B 嵌套了 事务 C,事务 C。。。。。

这种情况,在MySQL事务中是不会出现的。

 

Spring 的事务,就大不一样了!


因为我们代码,通常完成一个业务逻辑(事务),需要调用多个方法(事务),才能执行。

而多个多个方法又可能依赖于其他的方法,才得以实现。

这种情况,在 代码中 是非常常见的。

如果程序中出现这中嵌套的现象的话。

没问题的话,那还好,没有问题,

但是!万一出现了问题,那我们其它事务(方法)应该怎么去处理呢?


是相互不影响吗? 一个事务(方法)出现了问题,其它的事务不受影响。

还是 “引火上身”呢?一个事务牵扯到 ABC 三个事务,如果 一个事务出现了问题,其它的事务是是无法执行的,直接给你 进行 事务回滚了!

这个就涉及到 Spring 事务传播的机制是怎么设置的了


二、事务的实现

1、MySQL事务的回顾

详见MySQL的索引与事务(面试必考) - 细节狂魔_Dark And Grey的博客-CSDN博客

2、Spring声明式事务(利⽤注解⾃动开启和提交事务)

前置知识及概念

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


1、编程式事务(⼿动写代码操作事务)

编程式事务:通过代码来控制事务的 开启 和 提交,或者是 回滚。


2、 声明式事务(利用注解自动开启和提交事务)

声明式事务的实现很简单,只需要在需要的⽅法上添加 @Transactional 注解就可以实现了,⽆需⼿动开启事务和提交事务,进⼊⽅法时⾃动开启事务,⽅法执⾏完会⾃动提交事务,如果中途发⽣了没有处理的异常会⾃动回滚事务

默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。

@Transactional 可以⽤来修饰⽅法或类:

修饰⽅法时:需要注意只能应⽤到 public ⽅法上,否则不⽣效。推荐此种⽤法。

修饰类时:表明该注解对该类中所有的 public ⽅法都⽣效。


Spring的事务管理默认是针对***unchecked exception**回滚,也就是默认对Error异常和RuntimeException异常以及其子类进行事务回滚,且必须抛出异常,若使用try-catch对其异常捕获则不会进行事务回滚操作


因此


对于unchecked exception(Error和RuntimeException异常)抛出时不需要方法调用throws或try-catch语句

而checked exception 则必须用try语句块进行处理或者把异常交给上级方法处理,总之就是必须写代码处理它,所以必须在service捕获异常,然后再次抛出,这样事务方才起效。


关于异常详情见:异常

实例分析:事务的回滚

6b4df3e21f604d8fbe0587de9c006a1b.png


我们通过url模拟添加操作


7b0df13490d744e1abe82bb76d4a7d34.png

那么如果出现了异常,数据库中会不会添加这一条就记录呢?

deb45d1317cf4e79b131533cee0a488d.png


可以看到,我们再浏览器的url输入的lisi这条记录,没有成功添加到数据库中。


原因就是@Transactional 注解的自动回滚操作——》通过该注解,我们⽆需⼿动开启事务和提交事务,进⼊⽅法时⾃动开启事务,⽅法执⾏完会⾃动提交事务,如果中途发⽣了没有处理的异常会⾃动回滚事务


🔔特殊情况(无自动回滚)

36a35b6229474cd4a8b58d8ff2eb028a.png

我们再浏览器里继续上面的操作(尝试添加一条lisi的记录,看看有什么变化)

7b5d92087cb64a1982de8cd1ecc84981.png


3ec15c29549745ee8d751ffe9243d6c3.png

可以看到数据库中有了lisi这条数据——》@Transactional 在异常被捕获的情况下,不会进⾏事务⾃动回滚。

🔔事务不会⾃动回滚解决⽅案

解决⽅案1:对于捕获的异常,事务是会⾃动回滚的,因此解决⽅案1就是可以将异常重新抛出

2b1e5c4f2cc845569832d7e1440c6b68.png

  • 解决⽅案2:⼿动回滚事务,在⽅法中使⽤ TransactionAspectSupport.currentTransactionStatus() 可以得到当前的事务,然后设置回滚⽅法 setRollbackOnly 就可以实现回滚


0f26be0a28884a1e8e06a1e38a4378e4.png

🔔@Transactional工作原理

@Transactional 是基于 AOP 实现的,AOP ⼜是使⽤动态代理实现的。如果⽬标对象实现了接⼝,默认情况下会采⽤ JDK 的动态代理,如果⽬标对象没有实现了接⼝,会使⽤ CGLIB 动态代理。

@Transactional 在开始执⾏业务之前,通过代理先开启事务,在执⾏成功之后再提交事务。如果中途遇到的异常,则回滚事务。


@Transactional 实现思路预览:

16833efab3d342f6ba3008caf4fc21a0.png



相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
1月前
|
SQL Java 关系型数据库
Spring事务传播机制:7种姿势教你玩转"事务接力赛"
事务传播机制是Spring框架中用于管理事务行为的重要概念,它决定了在方法调用时事务如何传递与执行。通过7种传播行为,开发者可以灵活控制事务边界,适应不同业务场景。例如:REQUIRED默认加入或新建事务,REQUIRES_NEW独立开启新事务,NESTED支持嵌套回滚等。合理使用传播机制不仅能保障数据一致性,还能提升系统性能与健壮性。掌握这“七种人格”,才能在复杂业务中游刃有余。
|
2月前
|
Java 关系型数据库 数据库
深度剖析【Spring】事务:万字详解,彻底掌握传播机制与事务原理
在Java开发中,Spring框架通过事务管理机制,帮我们轻松实现了这种“承诺”。它不仅封装了底层复杂的事务控制逻辑(比如手动开启、提交、回滚事务),还提供了灵活的配置方式,让开发者能专注于业务逻辑,而不用纠结于事务细节。
|
7月前
|
Java Spring
Spring中事务失效的场景
因为Spring事务是基于代理来实现的,所以某个加了@Transactional的⽅法只有是被代理对象调⽤时, 那么这个注解才会⽣效 , 如果使用的是被代理对象调用, 那么@Transactional会失效 同时如果某个⽅法是private的,那么@Transactional也会失效,因为底层cglib是基于⽗⼦类来实现 的,⼦类是不能重载⽗类的private⽅法的,所以⽆法很好的利⽤代理,也会导致@Transactianal失效 如果在业务中对异常进行了捕获处理 , 出现异常后Spring框架无法感知到异常, @Transactional也会失效
|
7月前
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——常见问题总结
本文总结了Spring Boot中使用事务的常见问题,虽然通过`@Transactional`注解可以轻松实现事务管理,但在实际项目中仍有许多潜在坑点。文章详细分析了三个典型问题:1) 异常未被捕获导致事务未回滚,需明确指定`rollbackFor`属性;2) 异常被try-catch“吃掉”,应避免在事务方法中直接处理异常;3) 事务范围与锁范围不一致引发并发问题,建议调整锁策略以覆盖事务范围。这些问题看似简单,但一旦发生,排查难度较大,因此开发时需格外留意。最后,文章提供了课程源代码下载地址,供读者实践参考。
161 0
|
7月前
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
1034 0
|
7月前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——事务相关
本文介绍Spring Boot事务配置管理,阐述事务在企业应用开发中的重要性。事务确保数据操作可靠,任一异常均可回滚至初始状态,如转账、购票等场景需全流程执行成功才算完成。同时,事务管理在Spring Boot的service层广泛应用,但根据实际需求也可能存在无需事务的情况,例如独立数据插入操作。
186 0
|
5月前
|
人工智能 Java 数据库连接
Spring事务失效场景
本文深入探讨了Spring框架中事务管理可能失效的几种常见场景及解决方案,包括事务方法访问级别不当、方法内部自调用、错误的异常处理、事务管理器或数据源配置错误、数据库不支持事务以及不合理的事务传播行为或隔离级别。通过合理配置和正确使用`@Transactional`注解,开发者可以有效避免这些问题,确保应用的数据一致性和完整性。
272 10
|
4月前
|
Java 关系型数据库 MySQL
【Spring】【事务】初学者直呼学会了的Spring事务入门
本文深入解析了Spring事务的核心概念与使用方法。Spring事务是一种数据库事务管理机制,通过确保操作的原子性、一致性、隔离性和持久性(ACID),维护数据完整性。文章详细讲解了声明式事务(@Transactional注解)和编程式事务(TransactionTemplate、PlatformTransactionManager)的区别与用法,并探讨了事务传播行为(如REQUIRED、REQUIRES_NEW等)及隔离级别(如READ_COMMITTED、REPEATABLE_READ)。
382 1
|
7月前
|
SQL Java 数据库连接
Spring中的事务是如何实现的
1. Spring事务底层是基于数据库事务和AOP机制的 2. ⾸先对于使⽤了@Transactional注解的Bean,Spring会创建⼀个代理对象作为Bean 3. 当调⽤代理对象的⽅法时,会先判断该⽅法上是否加了@Transactional注解 4. 如果加了,那么则利⽤事务管理器创建⼀个数据库连接 5. 并且修改数据库连接的autocommit属性为false,禁⽌此连接的⾃动提交,这是实现Spring事务⾮ 常重要的⼀步 6. 然后执⾏当前⽅法,⽅法中会执⾏sql 7. 执⾏完当前⽅法后,如果没有出现异常就直接提交事务 8. 如果出现了异常,并且这个异常是需要回滚的就会回滚事务
|
监控 Java 数据库
Spring事务相关配置、案例:转账业务追加日志及事务传播行为
Spring事务相关配置、案例:转账业务追加日志及事务传播行为
173 0

热门文章

最新文章