美文网首页
Spring事务学习

Spring事务学习

作者: Spring_java | 来源:发表于2019-11-13 11:33 被阅读0次

    最近要去面试,有几个事务知识点需要复习下:

    1:在同一个Service中。A方法存在事务,创建异常,事务回滚

    事务1.jpg

    事务A方法开启了事务,结果数据库中没有新增数据,因为异常而回滚了。

    2:在同一个Service中,A没有事务,B有事务,A调用B方法。出现异常,但是事务不生效

    事务 2.jpg

    如图所示,不看注释的代码。A不存在事务,B存在事务,B中存在错误,A去调用B的方法。

    原始数据为:


    数据 4.jpg

    结果是:A插入数据成功,B删除成功,虽然发生异常,但是不会回滚。

    具体原因是:


    原始调用链路 9.jpg

    调用delete的方法时,是采用了this来调用
    当在一个类调用的时候,没有生成代理对象,是使用this来调用,结果就是不会去进行拦截来开启事务管理。
    数据库最终效果:


    数据6.jpg

    55为新插入的数据,而50就被删除了数据。

    2:在同一个Service中,A没有事务,B有事务,A调用B方法。出现异常,事务生效

    调用链路 8.jpg

    在这里,调用delete的方法是代理类来调用了。
    下面是解决方案:

    • 1.把方法B抽离到另外一个XXService中去,并且在这个Service中注入XXService,使用XXService调用方法B;
      显然,这种方式一点也不优雅,且要产生很多冗余文件,看起来很烦,实际开发中也几乎没人这么做吧?.反正我不建议
      采用此方案;

    • 2.通过在方法内部获得当前类代理对象的方式,通过代理对象调用方法B

      上面说了:动态代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理了!

      所以我们就使用代理对象来调用,就会触发事务;

    获取代理对象的方法:

    1.使用 ApplicationContext 上下文对象获取该对象;
    2.使用 AopContext.currentProxy() 获取代理对象,但是需要配置exposeProxy=true

    启动类加上注解: @EnableAspectJAutoProxy(exposeProxy = true)
    PlusService plusService = (PlusService) AopContext.currentProxy();
    使用接口的方式,而不是使用实现类,否则会报错
    

    结果: 新插入数据成功,但是异常导致删除数据出现回滚,没有删除


    数据 7.jpg

    相关文章

      网友评论

          本文标题:Spring事务学习

          本文链接:https://www.haomeiwen.com/subject/vflhictx.html