zoukankan      html  css  js  c++  java
  • spring的@Transaction使用注意

    文章参考资料 https://www.cnblogs.com/andy-zhou/p/5317866.html

     http://labreeze.iteye.com/blog/2277261

    Spring 事务的传递性介绍

        事务传播行为,所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

        TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

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

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

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

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

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

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

        这里需要指出的是,前面的六种事务传播行为是 Spring 从 EJB 中引入的,他们共享相同的概念。而 PROPAGATION_NESTED是 Spring 所特有的。以 PROPAGATION_NESTED 启动的事务内嵌于外部事务中(如果存在外部事务的话),此时,内嵌事务并不是一个独立的事务,它依赖于外部事务的存在,只有通过外部的事务提交,才能引起内部事务的提交,嵌套的子事务不能单独提交。如果熟悉 JDBC 中的保存点(SavePoint)的概念,那嵌套事务就很容易理解了,其实嵌套的子事务就是保存点的一个应用,一个事务中可以包括多个保存点,每一个嵌套子事务。另外,外部事务的回滚也会导致嵌套子事务的回滚。

    场景

    在同一个类或者不同类,controller层调用方法A,在方法A中,调用方法B,事务的传播机制

    这个是实际开发中的场景

    方法A与方法B在同一个类中

    结论

    同一个service中,被外部调用的方法A如果有事务,则方法A中所有方法均会使用方法A的事务,且子方法的事务失效

    方法A与方法B在不同一个类中

    结论

    不同一个service中,被外部调用的方法A如果有事务,则方法A中所有方法均会默认使用方法A的事务,如果B有事务,B会使用B的事务

    最后结论

    被外部调用的方法A如果有事务,则方法A中所有方法均会使用方法A的事务,

    在同类中子方法事务失效,

    不同类子方法事务生效

    新增操作回滚后,Id值已经被增加,不会回滚

    问题

    为什么同一个类中事务不能传递

    答:我们知道,Spring之所以可以对开启@Transactional的方法进行事务管理,是因为Spring为当前类生成了一个代理类,然后在执行相关方法时,会判断这个方法有没有@Transactional注解,如果有的话,则会开启一个事务。
    但是,上面这种调用方式时,在调用方法B时,使用的并不是代理对象,从而导致调用方法B时也不是代码对象,从而导致@Transactional失败。

    解决:

    1)xml 配置 <aop:aspectj-autoproxy expose-proxy="true"/>

    2)注解  @EnableAspectJAutoProxy(exposeProxy=true)表示通过aop框架暴露该代理对象,aopContext能够访问     ((Bean) AopContext.currentProxy()).methodB();

     3)ApplicationContextUtils.applicationContext(Bean).methodB

  • 相关阅读:
    web项目获取spring的applicationContext方式一
    idea关于tomcat中文乱码问题
    java面试题02
    JDBC连接步骤(三)
    JDBCAPI简介(二)
    JDBC简介(一)
    Maven(三)archetype
    如何javaSwing关闭子窗口不关闭父窗口
    Java中Object转化为int类型
    java double转int
  • 原文地址:https://www.cnblogs.com/shuaiandjun/p/9595634.html
Copyright © 2011-2022 走看看