Spring事务传播机制
# 先决条件
在了解Spring事务之前,我们要先了解什么是事务?
提示
事务:数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元);
# 事务的特性-ACID
- 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
- 一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
- 隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
- 持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。
# Spring事务
Spring事务管理本质上是对数据库事务管理的封装。Spring事务可以总结为三大要素:
- 数据源:表示具体的事务性资源,是事务的真正处理者,如MySQL等。
- 事务管理器:像一个大管家,从整体上管理事务的处理过程,如打开、提交、回滚等。
- 事务应用和属性配置:像一个标识符,表明哪些方法要参与事务,如何参与事务,以及一些相关属性如隔离级别、超时时间等。
Spring支持编程式事务管理以及声明式事务管理两种方式。
# 编程式事务管理
编程式事务管理是侵入性事务管理,使用TransactionTemplate或者直接使用PlatformTransactionManager,对于编程式事务管理,Spring推荐使用TransactionTemplate。
# 声明式事务管理
声明式事务管理建立在AOP之上,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。 编程式事务每次实现都要单独实现,但业务量大功能复杂时,使用编程式事务无疑是痛苦的,而声明式事务不同,声明式事务属于无侵入式,不会影响业务逻辑的实现,只需要在配置文件中做相关的事务规则声明或者通过注解的方式,便可以将事务规则应用到业务逻辑中。 显然声明式事务管理要优于编程式事务管理,这正是Spring倡导的非侵入式的编程方式。唯一不足的地方就是声明式事务管理的粒度是方法级别,而编程式事务管理是可以到代码块的,但是可以通过提取方法的方式完成声明式事务管理的配置。
# 事务的传播机制
事务的传播性一般用在事务嵌套的场景,比如一个事务方法里面调用了另外一个事务方法,那么两个方法是各自作为独立的方法提交还是内层的事务合并到外层的事务一起提交,这就是需要事务传播机制的配置来确定怎么样执行。
# 为什么需要事务的传播机制
场景一:ServiceA方法调用了ServiceB方法,两个方法都有事务,倘若ServiceB发生了异常,是让ServiceA提交还是让两个方法都回滚。
场景二:ServiceA方法调用了ServiceB方法,但是只有ServiceA方法加了事务,是否把ServiceB方法也加入ServiceA方法。倘若ServiceBy异常,是否回滚ServiceA?
场景三:ServiceA方法调用了ServiceB方法,两者都有事务,ServiceB已经执行完成,但ServiceA产生异常,是否回滚ServiceB?
# 生效条件
注意
spring使用aop来代理事务是针对于接口或类的,所以在同一个service类中两个方法的调用机制是不生效的.
# 事务的传播机制类型
# PROPAGATION_REQUIRED
- Spring默认的传播机制,能满足绝大部分业务需求。
- 如果外层有事务,则当前事务加入到外层事务,一块提交,一块回滚;
- 如果外层没有事务,新建一个事务执行。
# PROPAGATION_REQUES_NEW
- 每次都会新开启一个事务,同时把外层事务挂起;
- 当当前事务执行完毕,恢复上层事务的执行。
- 如果外层没有事务,执行当前新开启的事务即可。
# PROPAGATION_SUPPORT
- 如果外层有事务,则加入外层事务;
- 如果外层没有事务,则直接使用非事务方式执行。完全依赖外层的事务
# PROPAGATION_NOT_SUPPORT
- 该传播机制不支持事务,如果外层存在事务则挂起,执行完当前代码,则恢复外层事务,无论是否异常都不会回滚当前的代码
# PROPAGATION_NEVER
- 该传播机制不支持外层事务,即如果外层有事务就抛出异常
# PROPAGATION_MANDATORY
- 与NEVER相反,如果外层没有事务,则抛出异常
# PROPAGATION_NESTED
- 该传播机制的特点是可以保存状态保存点,当前事务回滚到某一个点,从而避免所有的嵌套事务都回滚,即各自回滚各自的,如果子事务没有把异常吃掉,基本还是会引起全部回滚的。
提示
传播规则回答了这样一个问题:一个新的事务应该被启动还是被挂起,或者是一个方法是否应该在事务性上下文中运行。