一、SpringBoot 事务原理
- 事务其实是建立在AOP的基础之上,其核心类就是 TransactionInterceptor,该类invokeWithinTransaction 方法是事务处理的核心方法,其中封装了我们创建的 DataSourceTransactionManager 对象,该对象就是执行回滚或者提交的执行单位
- 其实TransactionInterceptor 和我们平时标注@Aspect 注解的类的作用相同,就是拦截指定的方法,而在 TransactionInterceptor 中是通过是否标有事务注解来决定的。如果一个类中任意方法含有事务注解,那么这个方法就会被代理。
- 而Mybatis 的事务和Spring 的事务协作则根据他们的SqlSession是否是同一个SqlSession 来决定的,如果是同一个,则交给Spring,如果不是,Mybatis 则自己处理。而Mybatis 的事务和Spring 的事务协作则根据他们的SqlSession是否是同一个SqlSession 来决定的,如果是同一个,则交给Spring,如果不是,Mybatis 则自己处理。
二、 Spring 事务传播行为实例分析
spring支持7种事务传播行为,确定客户端和被调用端的事务边界(说得通俗一点就是多个具有事务控制的service的相互调用时所形成的复杂的事务边界控制)
以下示例中通用方法为:假设有类A的方法methodA(),有类B的方法methodB()。在methodA()中调用methodB()
1. PROPAGATION_REQUIRED(XML文件中为REQUIRED)
解释: 表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚)
示例:如果B的方法methodB()的事务传播特性是propagation_required
1> 如果A的方法包含事务,则B的方法则不从新开启事务;
2> 如果B的methodB()抛出异常,A的methodB()没有捕获,则A和B的事务都会回滚;
3> 如果B的methodB()运行期间异常会导致B的methodB()的回滚,A如果捕获了异常,并正常提交事务,则会发生Transaction rolled back because it has been marked as rollback-only的异常。
4> 如果A的methodA()运行期间异常,则A和B的Method的事务都会被回滚
2. PROPAGATION_SUPPORTS(XML文件中为SUPPORTS)
解释:表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行
示例:如果B的方法methodB()的事务传播特性是propagation_supports
1> 如果A的方法包含事务,则B运行在此事务环境中,如果A的方法不包含事务,则B运行在非事务环境;
2> 如果A没有事务,则A和B的运行出现异常都不会回滚。
3> 如果A有事务,A的method方法执行抛出异常,B.methodB和A.methodA都会回滚。
4> 如果A有事务,B.method抛出异常,B.methodB和A.methodA都会回滚,如果A捕获了B.method抛出的异常,则会出现异常Transactionrolled back because it has been marked as rollback-only。
3. PROPAGATION_MANDATORY(XML文件中为MANDATORY)
解释:表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常
示例:B.methodB()事务传播特性定义为:PROPAGATION_MANDATORY
1> 如果A的methodA()方法没有事务运行环境,则B的methodB()执行的时候会报如下异常:No existingtransaction found for transaction marked with propagation ‘mandatory’
2> 如果A的MethodA()方法有事务并且执行过程中抛出异常,则A.metho