Spring源码学习笔记

    一、Spring启动容器刷新12步

    二、Spring循环引用流程图

     三、SpringAop执行流程

 四、Spring事务的个人理解

        Spring事务的使用非常简单,只需要在需要开启事务的方法上加@Transactional(rollbackFor = Exception.class),但是有时候会出现事务失效的情况。事务失效的原因很多,比如没有用代理对象调用该方法或者异常在方法内部被吞了等等。其实本质上还是AOP在作怪。

        事务的概念本来是在数据库层面的概念,我们可以在数据库开启一个事务,执行一条sql,再根据具体情况决定提交还是回滚,如图

        

        只是现在,开启事务/提交事务/回滚事务  由交给Spring来做,我们只需要写要执行的sql语句。所以才有了Spring事务这个概念,本质上就是Spring通过程序的方式来帮我们实现了 开启事务/提交事务/回滚事务 这个过程。

        深入代码看下这个过程具体实现:

       对于没开启事务的类来说,自动注入的时候,是注入的一个原生的对象

       

       对于开启了事务的类来说,自动注入的时候,是注入了一个代理的对象

     

         深入看下这个代理对象,就会发现里面会有一个关于事务的增强

              

        当我们用代理对象调用被代理对象的方法时,首先会进入代理对象的intercept方法

        我们知道现在代理对象里面有一个事务增强器,但是并不是什么方法都需要事务增强器来增强,是那些打上@Transactional注解的方法才需要事务增强器来增强,所以Spring会根据当前调用的方法去判断,而这个过程就是getInterceptorsAndDynamicInterceptionAdvice来实现。

        点进去getInterceptorsAndDynamicInterceptionAdvice细看下实现,先把代理对象有的增强器拿来遍历,然后逐个match,如果match上就转成拦截器添加到集合,然后返回。

        此时我们也看到,放行后,我们确实也拿到了事务拦截器。事务拦截器也拿到了,接着我们来看看Spring是怎么将事务拦截器跟被代理的原生方法有机结合在一起来实现事务功能。

        

        沿着proceed一直点进去,可以看到整个事务就是由invokeWithinTransaction这个方法来实现。

        点进completeTransactionAfterThrowing和commitTransactionAfterReturning都能明显看到rollback跟commit的字眼。 

         现在就可以明白Spring事务失效的本质原因了。第一,事务的增强器以及事务的实现过程都是在代理对象中,所以你如果没用代理对象来调用,是不可能进入intercept方法,是不可能实现事务功能的。第二,如果异常被你程序内部吞了,那么invokeWithinTransaction方法就没法捕获到异常,也就没法执行回滚操作,所以也会出现事务失效。

        总结一下,Spring给我们程序员提供了强大的功能,我们只需要简单配置,就能使用Spring提供的强大功能,但是如果没有深入源码层面学习,了解Spring具体的执行流程,很可能就会因为配置出错,导致功能失效,造成生产事故。

        

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值