前言
事务对于 java web 应用来讲,也是比较大的一方面。面试的时候也会常常的问到,包含的内容有:java
- 事务的四大特性
- 事务的隔离级别
- spring 事务的传播机制
预期读者
对事务有必定基础的同窗,想弄清楚 spring 事务的传播机制git
为何会有传播机制
spring 对事务的控制,是使用 aop 切面实现的,咱们不用关心事务的开始,提交 ,回滚,只须要在方法上加 @Transactional
注解,这时候就有问题了。web
- 场景一: serviceA 方法调用了 serviceB 方法,但两个方法都有事务,这个时候若是 serviceB 方法异常,是让 serviceB 方法提交,仍是两个一块儿回滚。
- 场景二:serviceA 方法调用了 serviceB 方法,可是只有 serviceA 方法加了事务,是否把 serviceB 也加入 serviceA 的事务,若是 serviceB 异常,是否回滚 serviceA 。
- 场景三:serviceA 方法调用了 serviceB 方法,二者都有事务,serviceB 已经正常执行完,但 serviceA 异常,是否须要回滚 serviceB 的数据。
传播机制生效条件
由于 spring 是使用 aop 来代理事务控制 ,是针对于接口或类的,因此在同一个 service 类中两个方法的调用,传播机制是不生效的面试
传播机制类型
下面的类型都是针对于被调用方法来讲的,理解起来要想象成两个 service 方法的调用才能够。spring
PROPAGATION_REQUIRED (默认)
- 支持当前事务,若是当前没有事务,则新建事务
- 若是当前存在事务,则加入当前事务,合并成一个事务
REQUIRES_NEW
- 新建事务,若是当前存在事务,则把当前事务挂起
- 这个方法会独立提交事务,不受调用者的事务影响,父级异常,它也是正常提交
NESTED
- 若是当前存在事务,它将会成为父级事务的一个子事务,方法结束后并无提交,只有等父事务结束才提交
- 若是当前没有事务,则新建事务
- 若是它异常,父级能够捕获它的异常而不进行回滚,正常提交
- 但若是父级异常,它必然回滚,这就是和
REQUIRES_NEW
的区别
SUPPORTS
- 若是当前存在事务,则加入事务
- 若是当前不存在事务,则以非事务方式运行,这个和不写没区别
NOT_SUPPORTED
- 以非事务方式运行
- 若是当前存在事务,则把当前事务挂起
MANDATORY
- 若是当前存在事务,则运行在当前事务中
- 若是当前无事务,则抛出异常,也即父级方法必须有事务
NEVER
- 以非事务方式运行,若是当前存在事务,则抛出异常,即父级方法必须无事务
一点小说明
通常用得比较多的是 PROPAGATION_REQUIRED
, REQUIRES_NEW
;数据库
REQUIRES_NEW
通常用在子方法须要单独事务,暂时找不到例子,之后补充 。mybatis
完整的演示程序
https://gitee.com/sanri/example/tree/master/test-mybatis工具
一点小推广
Excel 通用导入导出,支持 Excel 公式
https://blog.csdn.net/sanri1993/article/details/100601578.net
使用模板代码 ,从数据库生成代码 ,及一些项目中常常能够用到的小工具
https://blog.csdn.net/sanri1993/article/details/98664034代理