zoukankan      html  css  js  c++  java
  • @Transactional 同一个类中无事务方法a()内部调用有事务方法b()的问题

    https://blog.csdn.net/u010235716/article/details/90171802

    1. 事务的4种特性        

    序号 参数 含义
    1 原子性(Atomicity) 事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行。
    2 一致性(Consistemcy) 事务前后,数据库的状态都满足所有的完整性约束。
    3 隔离性(Isolation) 并发执行的事务是隔离的,一个不影响一个。通过设置数据库的隔离级别,可以达到不同的隔离效果
    4 持久性(Durability) 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
    2.Transactional()控制事务传播的配置项目(默认Propagation.REQUIRED)

    @Transactional(propagation=Propagation.REQUIRED) //控制事务传播。默认是Propagation.REQUIRED
    @Transactional(isolation=Isolation.DEFAULT) //控制事务隔离级别。默认跟数据库的隔离级别相同
    @Transactional(readOnly=false) //控制事务可读写、只可读。默认可读写
    @Transactional(timeout=30) //控制事务的超时时间,单位秒。默认跟数据库的事务控制系统相同
    @Transactional(rollbackFor=RuntimeException.class) //控制事务遇到哪些异常会回滚。默认是RuntimeException
    @Transactional(rollbackForClassName=RuntimeException) //同上
    @Transactional(noRollbackFor=NullPointerException.class) //控制事务遇到哪些异常不会回滚。默认遇到RuntimeException回滚
    @Transactional(noRollbackForClassName=NullPointerException)//同上

    3.事务的7中传播特性4. 事务的传播案例:

    序号 传播行为 含义
    1 REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
    2 SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
    3 MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
    4 NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行
    5 NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常
    6 REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个已经存在的事务挂起
    7 NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务
    4.举个上手的按例:事务在A类的a()方法中调用B类的b()方法的传播案例

    A.a() B.b()的事务配置 a()没有事务的结果 a()有事务的结果
    REQUIRED b()创建自己的事务; b()接受a()的事务
    SUPPORTS b()不创建自己的事务; b()接受a()的事务
    MANDATORY b()报异常 b()接受a()的事务
    NESTED b()创建自己的事务; b()接受a()的事务,成为a()嵌套的子事务
    NEVER b()不创建自己的事务; b()报异常
    REQUIRES_NEW b()创建自己的事务; b()不接受a()的事务,b()先执行,内层事务失败不会影响外层事务
    NOT_SUPPORTED b()不创建自己的事务; b()不接受a()的事务,b()先执行

    spring 事务处理中,同一个类中:A方法(无事务)调B方法(有事务),事务不生效问题 

    详见:https://blog.csdn.net/liming19890713/article/details/79225894

    https://blog.csdn.net/m0_38027656/article/details/84190949

    https://blog.csdn.net/levae1024/article/details/82998386

    研究源码、调试程序得出结论:
    A如果没有受事务管理:  则线程内的connection 的 autoCommit为true。
    B得到事务时事务传播特性依然生效,得到的还是A使用的connection,但是 不会改变autoCommit的属性。
    所以B当中是按照每条sql进行提交的。

    解决办法:

    可以把方法B放到另外一个service或者dao,然后把这个server或者dao通过@Autowired注入到方法A的bean里面,这样即使方法A没用事务,方法B也可以执行自己的事务了。

    Spring 事务机制回顾

       Spring事务一个被讹传很广说法是:一个事务方法不应该调用另一个事务方法,否则将产生两个事务.  结果造成开发人员在设计                                                               事务方法时束手束脚,生怕一不小心就踩到地雷。 
      其实这是不认识Spring事务传播机制而造成的误解,Spring对事务控制的支持统一在TransactionDefinition类中描述,该类有以下   几个重要的接口方法:

    int getPropagationBehavior():事务的传播行为
    int getIsolationLevel():事务的隔离级别
    int getTimeout():事务的过期时间
    boolean isReadOnly():事务的读写特性
    除了事务的传播行为外,事务的其他特性Spring是借助底层资源的功能来完成的,Spring无非只充当个代理的角色。但是事务的传播行为却是Spring凭借自身的框架提供的功能 ;

    Spring事务传播属性:

       所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。Spring支持以下7种事务传播行为

    Spring事务传播属性:
    1.propagation-required: 支持当前事务,如果有就加入当前事务中;如果当前方法没有事务,就新建一个事务;
    2.propagation-supports: 支持当前事务,如果有就加入当前事务中;如果当前方法没有事务,就以非事务的方式执行;
    3.propagation-mandatory: 支持当前事务,如果有就加入当前事务中;如果当前没有事务,就抛出异常;
    4.propagation-requires_new: 新建事务,如果当前存在事务,就把当前事务挂起;如果当前方法没有事务,就新建事务;
    5.propagation-not-supported: 以非事务方式执行,如果当前方法存在事务就挂起当前事务;如果当前方法不存在事务,就以非事务方式执行;
    6.propagation-never: 以非事务方式执行,如果当前方法存在事务就抛出异常;如果当前方法不存在事务,就以非事务方式执行;
    7.propagation-nested: 如果当前方法有事务,则在嵌套事务内执行;如果当前方法没有事务,则与required操作类似;
    前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
    它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)
    在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解是不会生效的

  • 相关阅读:
    ADO.NET基础学习 二(Command对象)
    如何使ElementUI中的el-dropdown传入多参数
    Vue router Element 重复点击导航路由报错解决方法
    vue-svgicon基本使用
    js 两个相等的数组,修改其中一个怎么做到不改变另外一个
    LocalStorage存储JSON对象
    js取整数、取余数的方法
    JS正则截取两个字符串之间及字符串前后内容的方法
    Vuetify 表单规则验证
    JS正则表达式
  • 原文地址:https://www.cnblogs.com/lukelook/p/11246180.html
Copyright © 2011-2022 走看看