Spring事务的传播机制

事务传播机制是什么?(定义)

Spring 事务传播机制定义了多个包含了事务的⽅法,相互调⽤时,事务是如何在这些⽅法间进⾏传递的。总之,事务传播机制就是多个事务在相互调用时,事务是如何进行传递的。

为什么需要事务传播机制?

事务隔离级别是保证多个并发事务执⾏的可控性的(稳定性的),⽽事务传播机制是保证⼀个事务在多个调⽤⽅法间的可控性的(稳定性的)。

并发事务:多个事务同时调⽤⼀个数据库的问题

Spring事务的传播机制_第1张图片

事务传播机制:事务传播机制解决的是⼀个事务在多个⽅法中传递的问题 

Spring事务的传播机制_第2张图片

事务传播机制有哪些?

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事务的传播机制_第3张图片

Spring事务的传播机制使用示例:(演示加入事务REQUIRED和嵌套事务NESTED

加入事务REQUIRED示例:

controller代码如下:

 Spring事务的传播机制_第4张图片

UserService代码如下: 

 Spring事务的传播机制_第5张图片

LogInfoService代码如下:

Spring事务的传播机制_第6张图片 执行结果如下: 

Spring事务的传播机制_第7张图片 Spring事务的传播机制_第8张图片 此时会发现用户表和日志表都已经添加成功了,这是在没有异常的情况下。再次清除数据,我们手动在LogInfoService代码中构造一个算术异常,其他代码不变,再次运行,再来看数据表的变化: 

Spring事务的传播机制_第9张图片

Spring事务的传播机制_第10张图片

Spring事务的传播机制_第11张图片 

在数据库中可以发现用户表和日志表都没有添加成功。

小结:

加入当前事务:@Transactional(propagation = Propagation.REQUTRED)

方法调用流程: controller/add1 -〉用户添加方法->日志添加方法

当日志添加方法出现异常之后,加入事务的执行结果是:

1、用户添加成功的数据也回滚了

2. 日志添加成功的数据也回滚了

嵌套事务NESTED示例:

此示例与上面代码基本一样,只是传播机制设置不一样:

Spring事务的传播机制_第12张图片 Spring事务的传播机制_第13张图片

 在无异常情况下,数据均可以添加成功,执行结果如下:

Spring事务的传播机制_第14张图片

Spring事务的传播机制_第15张图片 再次清除数据,我们手动在LogInfoService代码中构造一个算术异常,其他代码不变,再次运行,再来看数据表的变化:

Spring事务的传播机制_第16张图片

执行结果如下:

Spring事务的传播机制_第17张图片 

Spring事务的传播机制_第18张图片

小结:

嵌套事务:@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 种。

你可能感兴趣的:(Spring全家桶,spring,java,数据库)