zoukankan      html  css  js  c++  java
  • Spring 事务传播行为的使用

                                                                                                                               Spring 事务传播行为的使用

    ★关键日志

      事务提交日志:
        Transaction synchronization committing SqlSession
        Transaction synchronization deregistering SqlSession
        Transaction synchronization closing SqlSession
           事务回滚日志:
        Transaction synchronization resuming SqlSession
        Transaction synchronization deregistering SqlSession
        Transaction synchronization closing SqlSession

    PROPAGATION详解

        不加事务:支持当前事务,如果没有事务就以非事务方式运行。

        PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

        PROPAGATION_SUPPORTS -- 支持当前事务(即能查询到update或insert,但是没有提交的东西--事务方法都是等方法执行完才提交), 如果当前没有事务,就以非事务方式执行。(在类中不加注解的情况下和不加事务是一样的,类中加了注解就可以加此注解来实现不加注解的情况)

        PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

        PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。


        PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。

        PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。


        PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行,如果执行失败,内部事务(即 ServiceB#methodB) 将回滚到它执行前的 SavePoint(回滚本身)。

                                                                  如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

    事务及嵌套事务的理解:


        1.Propagation.REQUIRED:同一个事务,一起成功或失败。注意:REQUIRED方法内的事务方法,不应该try-catch 而不抛出异常。


        2.Propagation.REQUIRES_NEW:完全是新的事务,回滚或提交不受外部影响。


        3.Propagation.NESTED的嵌套事务理解 :
          (1)回滚只是回滚内部方法本身,外部事务可以选择回滚/提交(try-catch方式处理的不同处理)
            PS:这点Propagation.REQUIRES_NEW也能做到。

          (2)外部事务提交回滚/提交,它也进行回滚/提交(它成功时的提交是在外部事务提交时)。
            PS:这点Propagation.REQUIRES_NEW做不到。

    异常:Transaction rolled back because it has been marked as rollback-only原因


        1.捕获后又抛出了不回滚的异常(默认RuntimeException才回滚,而Exception不回滚)。


        2.Propagation.REQUIRED A方法调用 Propagation.REQUIRED B方法,如果捕获了B方法中的异常没有抛出 或 捕获后又抛出了不回滚的异常(默认Exception不回滚)。

    Transactional的不回滚问题

        1、检查你方法是不是public的,public方法的Transactional注解才是有效的,才能控制事务。

        2、Spring默认只对UnChecked异常(RuntimeException)回滚,对于Checked(Exception)异常不回滚。
          你的异常类型是Checked异常。如果想check异常也想回滚怎么办? 
        (1)注解上加rollbackFor=Exception.class
        (2)对异常进行转换,转换成RuntimeException或自定义继承RuntimeException的异常

        3. 同一个类中的方法调用,内部方法的事务是没有效果的。
          如方法A没加事务,方法B中加了事务(不管加的是什么类型的事务)。方法A调用方法B,这样方法B中的事务是无效的。因为AOP只对A方法进行处理了,而不会对内部的B方法进行处理。

    父类中加了Transactional注解,子类中会继承。


      现象:service层继承了CommonSercice的方法默认。CommonSercice加了transaction注解,结果service层的每个方法都默认有了transaction注解(required)。


    项目实践(不一定遵守,怎么方便怎么用)


        1.不在类中加@Transactional,只在用到的方法中加。


        2.不用PROPAGATION_SUPPORTS,因为效果和不加是一样的。


        3.大多数事务:PROPAGATION_REQUIRED即可满足要求,要有rollbackFor=Exception.class,格式统一如下:
          @Transactional(propagation = Propagation.REQUIRED,rollbackFor=Exception.class)

  • 相关阅读:
    设计模式-策略模式
    设计模式-建造者模式
    js助手函数
    Javascript使用函数做命名空间
    腾讯云scf云函数,python依赖安装与上传的正确姿势
    nodejs爬虫,服务器经常返回ECONNRESET或者socket hang up错误的解决方法
    http请求,服务器回复内容为乱码的一种可能解决方法
    js在动态定义的新对象中,属性为变量时,如何动态定义
    nodejs中使用request时出现unable to verify the first certificate的一种解决办法
    Ubuntu偶然出现在待机解锁时,密码输入肯定正确但却无法进入的一种可能性
  • 原文地址:https://www.cnblogs.com/caoshouling/p/8644711.html
Copyright © 2011-2022 走看看