Spring事务

Spring事务是什么?

事务是一组操作的集合,这个集合内的所有操作都是不可分割的,说人话就是,要么所有的操作都要成功,要么都要失败

事务存在的意义

事务不只是属于sql专属的,在所有操作数据的都可以使用事务,事务的存在就是为了解决数据操作过程中出现的某些数据成功,某些数据失败引发的问题

事务的操作

  1. 开启事务:start transaction
  2. 提交事务: commit
  3. 回滚事务; rollback

Spring中事务的实现

  1. 编程式事务(手动进行开启和关闭事务)
  2. 声明式事务(使用注解进行自动开启和关闭事务)

编程式事务

Springboot中内置的两个对象

这个负责的是开启事务,提交和回滚事务

这个负责的是对事务的属性进行定义

整体过程

首先使用manager开启事务之后,需要把definition状态传入,然后进行提交或者回滚即可

提交事务成功示例

回滚事务示例

这里无论写什么都不会保存到数据库中去,因为在这一步,我们把数据进行了回滚,所以后续的操作都是无效的

虽然这种手动开启和关闭的可以实现事务,但是由于这种过程过于繁琐,所以我们这里更加推荐的是使用spring的注解方式来实现

Spring声明式事务

@Trasactional

如果版本太低就需要添加依赖

添加完依赖之后,只需要使用注解@Trasactional即可,只要遇到抛异常,那么就会进行回滚事务,如果没有发生异常就会提交

@Trasactional,既可以修饰类,也可以修饰方法,修饰类的时候,只对public修饰的方法起作用,推荐写在方法上

正常示例
抛异常示例

抛异常的时候就会导致全部的事务进行回滚

捕获异常并处理异常

只要不把异常交给jvm处理,自己捕获这个异常,那么就可以让事务正常的进行

怎么解决抛异常就无法会回滚事务的问题
捕获到异常之后不进行处理,继续抛出异常

由于我们捕获了异常,但是没有对这个异常进行处理,就会导致这个异常依然存在,最终还是会交给jvm进行处理,所以这个还是无法正常的进行事务的提交

手动回滚事务

进行手动的回滚事务即可

@Transactional详解

常见的属性

  1. RollbackFor:异常回滚属性,默认遇到runtimeexception和error才会进行回滚

遇到IO错误的话,就不会进行回滚,数据还是会正常的进行写入

如果需要指定回滚的异常类型,就需要通过rollbackfor属性进行指定

注意rollbackfor为数组,即可以指定多个异常回滚的类型

事务的隔离级别

MYSQL的事务隔离级别
读未提交

A开启了事务,写入或者删除数据,还没有结束事务,B就可以访问到A还没有提交的数据,这个问题叫做:脏读

读已提交

B开始查询,得到第一次结果,A开启了事务,然后进行进行了数据的写入或删除然后提交,B这个时候进行查询,得到的结果和之前的不一样,这个问题叫做:不可重复读

可重复读

A开始查询,这个时候B插入一条数据,由于可重复读会让每次读到的数据都保持一致,但是B插入数据,他是可以感知到的,也就是说,如果这个时候A插入数据,就会出现问题,因为主键是唯一的,明明就是查不到这个数据,但是自己的插入却是一直失败,这个问题就叫做:幻读

串行化

事务的最高隔离级别,强制事务进行排序,一个个来,只有上一个结束之后,才会被允许下一个,这个解决了脏读,不可重复读和幻读的问题,但是效率十分的低下

Spring的隔离级别

Spring的隔离级别有5种:

第一种,隔离级别保持和连接的数据库的隔离级别一样

其他的四种隔离级别就分别和mysql的隔离级别一一对应

Spring 中事务隔离级别可以通过 1 2 @Transactional 中的 isolation 属性进⾏设置

Spring的事务传播机制

事务的传播机制

当多个事务方法存在调用关系的时候,事务就会进行传播,这个是如何进行的呢

事务的传播机制有7种

举例子

REQUIRED

如果当前A有事务B就加入该事务,如果A没有事务B就单独创建一个新的事务,注意这个时候B创建的事务是只属于B的,和A没有任何的关系

SUPPORTS

如果当前A有事务,那么B就加入该事务,如果A没有事务,那么B就不创建事务,以非事务的方式继续运行

MANDATORY

强制性,A必须有事务,A有事务B就会加入,A没有事务的话B就直接抛异常

REQUIRES_NEW

不管A有没有事务,B都会创建一个新的事务,如果A有事务,B就把A的事务挂起,然后相互独立运行

NOT_SUPPORTED

无论A有没有事务,B不创建事务,都以非事务的方式运行

NEVER

不允许A有事务,如果A有事务,那么就直接抛出异常

NESTED

如果A存在事务,那么B也会创建一个事务,嵌套在A事务之内,如果B的事务发生了异常,如果他自己处理好了,就不会影响到A事务,如果A事务发生了异常没有处理好,就会导致整个事务全部发生异常

如果A不存在事务,那么B就自己创建事务,然后独立的运行

重点事务传播机制
  1. REQUIRED(默认值)
  2. REQUIRES_NEW

总结

  1. Spring中使⽤事务,有两种⽅式:编程式事务(⼿动操作)和声明式事务.其中声明式事务使⽤较多,在 ⽅法上添加 @Transactional 就可以实现了

  2. 通过 @Transactional(isolation = Isolation.SERIALIZABLE) 设置事务的隔离级 别.Spring中的事务隔离级别有5种

  3. 通过@Transactional(propagation =Propagation.REQUIRED)设置事务的传播机制,Spring中的 事务传播级别有7种,重点关注 REQUIRED (默认值)和 REQUIRES_NEW

相关推荐
Dxy123931021613 分钟前
MySQL如何高效查询表数据量:从基础到进阶的优化指南
数据库·mysql
Dying.Light16 分钟前
MySQL相关问题
数据库·mysql
源代码•宸27 分钟前
大厂技术岗面试之谈薪资
经验分享·后端·面试·职场和发展·golang·大厂·职级水平的薪资
Anastasiozzzz36 分钟前
Java Lambda 揭秘:从匿名内部类到底层原理的深度解析
java·开发语言
骇客野人37 分钟前
通过脚本推送Docker镜像
java·docker·容器
蜡笔小炘1 小时前
LVS -- 利用防火墙标签(FireWall Mark)解决轮询错误
服务器·数据库·lvs
韩立学长1 小时前
基于Springboot泉州旅游攻略平台d5h5zz02(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·旅游
铁蛋AI编程实战1 小时前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
晚霞的不甘1 小时前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
SunnyDays10111 小时前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列