事务传播机制是什么?(定义)
Spring 事务传播机制定义了多个包含了事务的⽅法,相互调⽤时,事务是如何在这些⽅法间进⾏传递的。总之,事务传播机制就是多个事务在相互调用时,事务是如何进行传递的。
为什么需要事务传播机制?
事务隔离级别是保证多个并发事务执⾏的可控性的(稳定性的),⽽事务传播机制是保证⼀个事务在多个调⽤⽅法间的可控性的(稳定性的)。
并发事务:多个事务同时调⽤⼀个数据库的问题
事务传播机制:事务传播机制解决的是⼀个事务在多个⽅法中传递的问题
事务传播机制有哪些?
Spring 事务传播机制包含以下 7 种:
Propagation.REQUIRED:默认的事务传播级别,它表示如果当前存在事务,则加⼊该事务;如果当前没有事务,则创建⼀个新的事务。
Propagation.SUPPORTS:如果当前存在事务,则加⼊该事务;如果当前没有事务,则以⾮事务的⽅式继续运⾏。
Propagation.MANDATORY:(mandatory为强制性的)如果当前存在事务,则加⼊该事务;如果当前没有事务,则抛出异常。
Propagation.REQUIRES_NEW:表示创建⼀个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部⽅法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部⽅法会新开启⾃⼰的事务,且开启的事务相互独⽴,互不⼲扰。
Propagation.NOT_SUPPORTED:以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起。
Propagation.NEVER:以⾮事务⽅式运⾏,如果当前存在事务,则抛出异常。
Propagation.NESTED:如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏;如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED。
根据是否⽀持当前事务分为以下3类:
Spring事务的传播机制使用示例:(演示加入事务REQUIRED和嵌套事务NESTED)
加入事务REQUIRED示例:
controller代码如下:
UserService代码如下:
LogInfoService代码如下:
执行结果如下:
此时会发现用户表和日志表都已经添加成功了,这是在没有异常的情况下。再次清除数据,我们手动在LogInfoService代码中构造一个算术异常,其他代码不变,再次运行,再来看数据表的变化:
在数据库中可以发现用户表和日志表都没有添加成功。
小结:
加入当前事务:@Transactional(propagation = Propagation.REQUTRED)
方法调用流程: controller/add1 -〉用户添加方法->日志添加方法
当日志添加方法出现异常之后,加入事务的执行结果是:
1、用户添加成功的数据也回滚了
2. 日志添加成功的数据也回滚了
嵌套事务NESTED示例:
此示例与上面代码基本一样,只是传播机制设置不一样:
在无异常情况下,数据均可以添加成功,执行结果如下:
再次清除数据,我们手动在LogInfoService代码中构造一个算术异常,其他代码不变,再次运行,再来看数据表的变化:
执行结果如下:
小结:
嵌套事务:@Transactional(propagation = Propagation.NESTED)
方法调用流程: controller/add1 -〉用户添加方法->日志添加方法
当日志添加方法出现异常之后,嵌套事务的执行结果是:
1、用户数据添加成功了
2. 日志添加成功的数据回滚了
嵌套事务(NESTED)和加⼊事务(REQUIRED )的区别:
整个事务如果全部执⾏成功,⼆者的结果是⼀样的。如果事务执⾏到⼀半失败了,那么加⼊事务整个事务会全部回滚;⽽嵌套事务会局部回滚,不会影响上⼀个⽅法中执⾏的结果。
总结:
1. 在 Spring 项⽬中使⽤事务,⽤两种⽅法,⼿动操作和声明式⾃动提交,其中后者使⽤的最多,在⽅法上添加 @Transactional 就可以实现了。
2. 设置事务的隔离级别 @Transactional(isolation = Isolation.SERIALIZABLE),Spring 中的事务隔离级别有 5 种。
3. 设置事务的传播机制 @Transactional(propagation = Propagation.REQUIRED),Spring 中的事务传播级别有 7 种。