Spring事务是什么?
事务是一组操作的集合,这个集合内的所有操作都是不可分割的,说人话就是,要么所有的操作都要成功,要么都要失败
事务存在的意义
事务不只是属于sql专属的,在所有操作数据的都可以使用事务,事务的存在就是为了解决数据操作过程中出现的某些数据成功,某些数据失败引发的问题
事务的操作
- 开启事务:start transaction
- 提交事务: commit
- 回滚事务; rollback
Spring中事务的实现
- 编程式事务(手动进行开启和关闭事务)
- 声明式事务(使用注解进行自动开启和关闭事务)
编程式事务

Springboot中内置的两个对象

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

这个负责的是对事务的属性进行定义
整体过程
首先使用manager开启事务之后,需要把definition状态传入,然后进行提交或者回滚即可
提交事务成功示例

回滚事务示例

这里无论写什么都不会保存到数据库中去,因为在这一步,我们把数据进行了回滚,所以后续的操作都是无效的
虽然这种手动开启和关闭的可以实现事务,但是由于这种过程过于繁琐,所以我们这里更加推荐的是使用spring的注解方式来实现
Spring声明式事务
@Trasactional
如果版本太低就需要添加依赖

添加完依赖之后,只需要使用注解@Trasactional即可,只要遇到抛异常,那么就会进行回滚事务,如果没有发生异常就会提交
@Trasactional,既可以修饰类,也可以修饰方法,修饰类的时候,只对public修饰的方法起作用,推荐写在方法上
正常示例


抛异常示例

抛异常的时候就会导致全部的事务进行回滚
捕获异常并处理异常

只要不把异常交给jvm处理,自己捕获这个异常,那么就可以让事务正常的进行
怎么解决抛异常就无法会回滚事务的问题
捕获到异常之后不进行处理,继续抛出异常

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

进行手动的回滚事务即可
@Transactional详解
常见的属性
- 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就自己创建事务,然后独立的运行
重点事务传播机制
- REQUIRED(默认值)
- REQUIRES_NEW
总结
-
Spring中使⽤事务,有两种⽅式:编程式事务(⼿动操作)和声明式事务.其中声明式事务使⽤较多,在 ⽅法上添加 @Transactional 就可以实现了
-
通过 @Transactional(isolation = Isolation.SERIALIZABLE) 设置事务的隔离级 别.Spring中的事务隔离级别有5种
-
通过@Transactional(propagation =Propagation.REQUIRED)设置事务的传播机制,Spring中的 事务传播级别有7种,重点关注 REQUIRED (默认值)和 REQUIRES_NEW