简单学习 --> Spring事务

Spring事务和事务的传播机制

事务

多个步骤放在同一个事务里,那么执行这些步骤,要么 这些步骤都执行成功, 要么这些事务都执行失败 ;

复制代码
转账: b转给A100元
A+100元
b-100元      这两个步骤必须都成功执行,或者都执行失败 ; 

Spring对于事务的实现

  1. 编程式(手动式) 了解

  2. 声明式(注解式) 重点

事务的执行
复制代码
start 开启事务 ->  如果错误 rollback回滚  -> 完成工作 commit提交

编程式(手动式) 实现事务

需要两个对象: DatasourceTransactionManager(用来管理事务) , TransactionDefinition (用来获取事务)
获取事务 : TransactionStatus , (事务就会记录当前数据的状态)
回滚或提交事务

通过事务管理器, 来管理 前面获取的 "事务"; (获取的"事务", 记录了数据的状态 , 当回滚时, 就把数据恢复到 "事务" 的时候 ,

在MySQL , 事务需要进行提交后 , 数据才会被修改 , 而这里 , 即使没有提交, 数据已经发生了修改)

回滚和提交事务 区别

声明式(注解式) 实现事务

@Transactional 注解

通过@Transactional注解来实现事务 ; 这个注解就是使用 AOP ,

  1. 目标方法执行前 , 获取 事务

  2. 执行目标方法

  3. 目标方法执行后 , 提交事务 (当目标方法成功执行后)

  4. 目标方法执行异常 , 回滚事务

当 目标方法正常执行

目标方法发生异常 ;

发生异常后 ,是直接回滚的, 并没有提交事务 ;

@Transactional 作用域

@Transactional 可以 修饰方法和类,

  1. 修饰方法时 , 只有修饰public方法 ,才能生效 ; 修饰其他方法不报错,不生效 ;

  2. 修饰类时 , 对 类里 所有的 public 方法生效 ;

@Transactional 详解
1.rollbackFor 属性

rollbackFor: 当发生什么事情, 就 回滚

(这4个都是同一类东西 , 有根据类名的,有根据其他的,)

@Transactional 注解, 在默认情况下 , 只有遇到 RuntimeException(运行时异常) 或 Error(错误) , 才不提交事务,而 触发回滚 ; 其他状态 则默认 提交事务 ;
通过rollbackFor属性设置 回滚

设置所有异常情况, 都让 事务回滚

当对异常进行了捕获处理,那么@Transactional 仍然进行提交事务,不进行回滚;
设置捕获了异常,仍然回滚

捕获异常,让异常在内部就处理了, @Transacional 就感知不到, 设置捕获异常,仍然回滚(捕获到异常只是为了打个日志), 2个方法

1. 把捕获的异常重新抛出

2. 手动设置回滚

通过 : TransactionAspectSupport 来获取 当前的事务 , 然后设置回滚 ; 这样即使捕获了异常, 但仍然回滚 ;

事务的隔离级别

SQL标准: 四种隔离级别

  1. 读未提交 (READ UNCOMMITTED) : 也叫未提交读, 这个级别的事务,可以读到其他事务中未提交的数据(未提交的数据,可能发生回滚, 所以这些数据也 称为 "脏数据" , 这个问题也叫 "脏读")

  2. 读已提交 (READ COMMITED): 也叫 提交读 , 可以读到 已经提交事务 的数据; (有一个问题: 1小时前读到的数据 list1 , 现在读到的数据 list2 , 可能因为其他事务的提交,导致 list2 和 list1 读的数据不同 , 这个问题 叫 "不可重复读" )

  3. 可重复读 (REPEATABLE READ) : 解决 "不可重复读"的 问题 , 可重复读 ,在 同一个事务中 , 确保读到的数据是一致的; (对修改无所谓,事务不会读掉其他事务,对已有数据的修改, 即使其他事务已经提交; 但是对 "插入数据 " 是 "可以感知到的 " , 所以 又会出现 "幻读 " 的问题 , "可重复读是MySQL默认的事务隔离级别")

(幻读 : 当前事务是可重复读级别的, 如果有其他事务对 数据进行 插入新的数据 , 因为 当前事务每次读到的数据都是同样的 , 所以导致 自己 读不到 这个新插入的数据 , 自己重复插入时又失败了(因为唯一性的约束) , 明明自己没看到有这条数据 ,但是却插入不了这个数据 , 这个就是 "幻读" )

4**. 串行化** (serializable): 可序列化的 , 事务最高隔离级别 , 强制事务排序(一个执行完到另一个) , 让事务不会发生影响, 解决了 脏读, 不可重复读 , 幻读问题(用的比较少)

Spring 事务的隔离级别

Spring 事务隔离级别有 5种 ; 通过@Transactional 注解里的 isolation 属性修改

  1. Isolation.DEFAULT : 是 按数据库的 默认级别 , 来设置事务级别 ;

  2. 其他的4个 和上面的 数据4种 事务级别一致 ;

Spring事务的传播机制

事务的传播

当一个A方法加上了@Transactional 事务 , 方法 里 调用了 B 方法 , B方法 也有@Transactional ,也加了事务 ;

这样一个事务里 ,嵌套了 另一个事务 , 这多个事务是怎么执行的 , 此时 B 方法是 加入A 方法的事务 , 还是执行B方法的事务

(数据库里很少有这样的问题 , 是因为不会像这样 事务嵌套另一个事务);

事务的传播机制

Propagation(传播)

Spring 事务的传播机制一共有 7种 ,在 Transactional注解中有Propagation属性来设置

Propagation 枚举类

嵌套事务: 根据当前事务,创建保存点, 如果发生异常,就回滚到保存点 , 如果没有事务,就按REQUIRED 来处理

使用情况

t1 有一个默认的事务, t1里调用 insertUser 方法 和 inserLog 方法 , 在两个方法的事务使用 不同的 传播机制 ;

  1. REQUIRED : 当有任意一个方法 发生异常, 都会发生回滚

  2. REQUIRES_NEW : 因为即使t1有事务, insertUser和 insertLog也不用, 自己创建 自己的 事务, 所以user和log两个事务不会相互影响

  3. NEVER : 不允许有事务, 有事务则抛异常

  4. NESTED(嵌套): 当有一个方法发生异常,发生回滚(但可以实现部分回滚)

REQUIRED 和 NESTED(嵌套) 的区别
  1. NESTED(嵌套事务) , 就类似于 '子事务' , t1方法有一个主事务 , insertUser和 insertLog 都根据 t1的事务, 创建子事务 ;

  2. NESTED 可以实现 "部分回滚 " , REQUIRED 事务,可以看作是一个整体 , t1 和 insertUser 和 insertLog都是用一个事务, 当任何一个方法发生异常, 都发生回滚, 回滚整体 ;

  3. 而 NESTED 是子事务 , 如果子事务 里发生异常, 如果子事务里处理了异常, 是完全不影响 主事务的 ; 如果处理不好 , 就 让主事务处理 (例如 t1是主事务 , insertUser 和 insertLog是 子事务 , 如果 insertUser 里发生异常, 自己处理掉的话 , t1是感知不到的, 也就不用整个都回滚 , 如果 处理不当,就交给t1里处理 ; )

  4. 正常情况提交,是基本都是没有区别

部分回滚
  1. 例如: t1是主事务 , insertUser 和 insertLog 方法 里都是 NESTED 嵌套事务 , 当 insertLog 发生异常 , 那么我们用try catch 捕获事务后, 手动进行回滚 , 实现 insertLog 的回滚 ;

  2. 因为只回滚了 insertLog的子事务, 所以 user表正常插入了数据, 而 log表 回滚了

  3. 如果是REQUIRED , 则这里回滚的是整个回滚, 不能部分回滚

相关推荐
前进的李工1 小时前
MySQL慢查询日志优化实战
数据库·mysql·性能优化
KaMeidebaby2 小时前
卡梅德生物技术快报|禽类成纤维细胞 FISH 实验:鸟类性别染色体基因定位技术实现与数据验证
前端·数据库·其他·百度·新浪微博
ECT-OS-JiuHuaShan2 小时前
彻底定理化:从量子纠缠到量子代谢
数据库·人工智能·学习·算法·生活·量子计算
八月瓜科技2 小时前
用AI来省电?iOS26.5正式版全球推送:信号弱网双提升,AI省电模式上新
数据库·人工智能·科技·深度学习·机器人
dhashdoia2 小时前
GPT-5.5 代码开发实战:Codex与Browser Use深度集成与星链4SAPI优化方案
java·数据库·人工智能·gpt·架构
小陈phd2 小时前
多模态大模型学习笔记(四十)——从“看字”到“懂结构”:版面分析与表格解析技术全解
笔记·学习
xuhaoyu_cpp_java2 小时前
SpringMVC学习(二)
java·经验分享·笔记·学习·spring
qq_283720053 小时前
LangChain+FAISS 向量数据库搭建轻量化 RAG 应用
数据库·langchain·faiss