@Transactional详解

Transactional七大事务传播行为

1、TransactionDefinition.PROPAGATION_REQUIRED:
      如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。

2、TransactionDefinition.PROPAGATION_REQUIRES_NEW:
      创建一个新的事务,如果当前存在事务,则把当前事务挂起。

3、TransactionDefinition.PROPAGATION_SUPPORTS:
      如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

4、TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
      以非事务方式运行,如果当前存在事务,则把当前事务挂起。

5、TransactionDefinition.PROPAGATION_NEVER:
      以非事务方式运行,如果当前存在事务,则抛出异常。

6、TransactionDefinition.PROPAGATION_MANDATORY:
       如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

7、TransactionDefinition.PROPAGATION_NESTED:
      如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;
如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

为什么Transactional必须要用Public修饰呢?

Spring AOP有两种CglibAopProxyJdkDynamicAopProxy,其中:

CglibAopProxy在其内部类DynamicAdvisedInterceptorintercept()方法中,判断是否进行事务拦截。

JdkDynamicAopProxy在其invoke()方法中,判断是否进行事务拦截。
这两个方法都会间接调用AbstractFallbackTransactionAttributeSource类的computeTransactionAttribute方法来获取事务控制的相关属性。这其中有以下一段代码:
在这里插入图片描述
在这段代码里,方法no-public的都直接返回null了.

详细介绍

在这里插入图片描述
按这种方式删完数据抛出异常是肯定能回滚的,我们来看另一种,把@Transactional元注解写在被method B上的情况。
在这里插入图片描述
按照之前的想法,我觉得这样子也是肯定能回滚的,但实际上数据并不会回滚,原因就得从他的实现原理了解起了.

@Transactional事务实现机制

整体事务流程
  1. @Transactional注解的方法被类外部的代码调用时,Spring在运行时为方法所在类生成一个AOP代理对象。
  2. 代理对象根据@Transactional的属性,决定是否由事务拦截器TransactionInterceptor对此方法进行事务拦截。
  3. 在进行事务拦截时,会先开启事务,然后执行业务代码,根据执行是否出现异常,通过抽象事务管理器AbstractPlatformTransactionManager来进行rollback或者commit
上通俗易懂的图解

为什么第一张图有效,第二张图,事务并没有起效呢?看图
在这里插入图片描述

Spring在检查到@Transactional注解之后,给这个对象生成了一个代理对象proxy
代理对象的methodB,会先开启事务(beginTransaction),然后再去执行原先对象target的methodB,如果抛异常,则回滚(rollBack),如果一切顺利,则提交(commit)。

而最后注入Spring容器的,也正是这个带有事务逻辑的代理对象。所以我们调用methodB时会产生事务。

接下来我们加一个method A看看效果:
在这里插入图片描述

由于methodA没有加@Transactional注解,所以代理对象里面,直接就是target.methodA(),直接调用了原来对象的methodA。

这下就很清晰了,代理对象的methodA,去调用原来对象的methodA,原来对象的methodA,再去调用原来对象的methodB,而原来对象的methodB,是不具有事务的。事务只存在于代理对象的methodB. 所以整个方法也就没有事务了。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值