Spring事务传播行为

概述
  • Spring在TransactionDefinition接口中规定了7种类型的事务传播行为
  • 事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为。

    事务的分类
  • Java事务类型分为JDBC事务跟JTA事务
    • JDBC事务:即为上面说的数据库事务中的本地事务,通过connection对象控制管理。
    • JTA事务:JTA指Java事务API(Java Transaction API),是Java EE数据库事务规范, JTA只提供了事务管理接口,由应用程序服务器厂商(如WebSphere Application Server)提供实现,JTA事务比JDBC更强大,支持分布式事务。
  • 按是否通过编程
    • 声明式事务:通过XML配置或者注解实现。
    • 编程式事务:通过编程代码在业务逻辑时需要时自行实现,粒度更小。
数据库特性
  • 事务的数据库,都必须具备四个特性,分别是:

    • 原子性(Atomicity)
    • 一致性(Consistency)
    • 隔离性(Isolation)
    • 持久性(Durability)

      隔离级别
  • 数据库隔离级别
    • Read-Uncommitted (未提交读)
    • Read-Committed (提交读)
    • Repeatable-Read(可重复读)
    • Serializable (可串行化)
  • Spring中的隔离级别 (除了第一种,剩余四个可以对应数据库的隔离级别)
    • ISOLATION_DEFAULT 这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与 JDBC 的隔离级别相对应。
    • ISOLATION_READ_UNCOMMITTED
    • ISOLATION_READ_COMMITTED
    • ISOLATION_REPEATABLE_READ
    • ISOLATION_SERIALIZABLE

      Spring中七种事务传播行为
  • PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
  • PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与- PROPAGATION_REQUIRED类似的操作。
spring的事务超时
Java 中定义了两类异常
  • 1) Checked exception: 这类异常都是Exception的子类。异常的向上抛出机制进行处理,假如子类可能产生A异常,那么在父类中也必须throws A异常。可能导致的问题:代码效率低,耦合度过高。
  • 2) Unchecked exception: 这类异常都是RuntimeException的子类,虽然RuntimeException同样也是Exception的子类,但是它们是非凡的,它们不能通过client code来试图解决,所以称为Unchecked exception 。

    事务回滚规则
  • Spring的事务管理默认是针对unchecked exception回滚,也就是默认对Error异常和RuntimeException异常以及其子类进行事务回滚,且必须抛出异常
  • 若使用try-catch对其异常捕获则不会进行回滚!(Error异常和RuntimeException异常抛出时不需要方法调用throws或try-catch语句);而checked exception 则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它,所以必须在service捕获异常,然后再次抛出,这样事务方才起效。

使用
  • @Transactional(propagation=Propagation.REQUIRED)

    • propagation 属性 事务的传播行为,默认值为 Propagation.REQUIRED。
    • isolation 属性 事务的隔离级别,默认值为 Isolation.DEFAULT。
    • timeout 属性 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
    • readOnly 属性 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
    • rollbackFor 属性 用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。
    • noRollbackFor 属性 抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。
事务不回滚的原因
  • 声明式事务配置切入点表达式写错了,没切中Service中的方法
  • Service方法中,把异常给try catch了,但catch里面只是打印了异常信息,没有手动抛出RuntimeException异常
  • Service方法中,抛出的异常不属于运行时异常(如IO异常),因为Spring默认情况下是捕获到运行时异常就回滚
@Transactional事务几点注意
  • 不要在接口上声明@Transactional ,而要在具体类的方法上使用 @Transactional 注解,否则注解可能无效。
  • 不要图省事,将@Transactional放置在类级的声明中,放在类声明,会使得所有方法都有事务。故@Transactional应该放在方法级别,不需要使用事务的方法,就不要放置事务,比如查询方法。否则对性能是有影响的。
  • 使用了@Transactional的方法,对同一个类里面的方法调用, @Transactional无效。比如有一个类Test,它的一个方法A,A再调用Test本类的方法B(不管B是否public还是private),但A没有声明注解事务,而B有。则外部调用A之后,B的事务是不会起作用的。(经常在这里出错)
  • 使用了@Transactional的方法,只能是public,@Transactional注解的方法都是被外部其他类调用才有效,故只能是public。道理和上面的有关联。故在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错,但事务无效。
  • spring的事务在抛异常的时候会回滚,如果是catch捕获了,事务无效。可以在catch里面加上throw new RuntimeException();
  • 经过在ICORE-CLAIM中测试,效果如下

    A.抛出受查异常XXXException,事务会回滚。
    B.抛出运行时异常NullPointerException,事务会回滚。
    C.Quartz中,execute直接调用加了@Transactional方法,可以回滚;间接调用,不会回滚。(即上文3点提到的)
    D.异步任务中,execute直接调用加了@Transactional方法,可以回滚;间接调用,不会回滚。(即上文3点提到的)
    E.在action中加上@Transactional,不会回滚。切记不要在action中加上事务。
    F.在service中加上@Transactional,如果是action直接调该方法,会回滚,如果是间接调,不会回滚。(即上文3提到的)
    G.在service中的private加上@Transactional,事务不会回滚。

Spring事务梳理的更多相关文章

  1. 【面试】足够应付面试的Spring事务源码阅读梳理(建议珍藏)

    Starting from a joke 问:把大象放冰箱里,分几步? 答:三步啊,第一.把冰箱门打开,第二.把大象放进去,第三.把冰箱门带上. 问:实现Spring事务,分几步? 答:三步啊,第一. ...

  2. spring事务详解(五)总结提高

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.概念 ...

  3. spring 事务源码赏析(二)

    我们在spring 事务源码赏析(一) 中分析了spring事务是如何找到目标方法,并如何将事务的逻辑织入到我们的业务逻辑中.本篇我们将会看到spring事务的核心实现: 1.事务传播机制的实现 2. ...

  4. Spring事务专题(五)聊聊Spring事务到底是如何实现的

    前言 本专题大纲: 本文为本专题倒数第二篇文章. 在上篇文章中我们一起学习了Spring中的事务抽象机制以及动手模拟了一下Spring中的事务管理机制,那么本文我们就通过源码来分析一下Spring中的 ...

  5. spring事务:事务控制方式,使用AOP控制事务,七种事务传播行为,声明事务,模板对象,模板对象原理分析

    知识点梳理 课堂讲义 1)事务回顾 1.1)什么是事务-视频01 事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败. 1.2)事务的作用 事务特征(ACID) 原子 ...

  6. spring事务概念理解

    1.数据并发问题 脏读 A事务读取B事务尚未提交的更新数据,并在此数据的基础上操作.如果B事务回滚,则A事务读取的数据就是错误的.即读取了脏数据或者错误数据. 不可重复组 A事务先后读取了B事务提交[ ...

  7. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  8. Spring事务

    1.@Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.@Transactional 的 ...

  9. spring事务管理器设计思想(二)

    上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务.这是最常见 ...

随机推荐

  1. kali机获取不到ip地址解决

    一.方法一 重启网卡:/etc/init.d/networking restart 重启kali:reboot 二.方法二 更改网络适配器:虚拟机-可移动设备-网络适配器设置-选择“桥接模式:直接连接 ...

  2. CodeTypeDeclaration,CodeMemberProperty动态生成代码

    由于是CodeDom些列,所以先介绍几个CodeDom表达式: :CodeConditionStatement:判断语句即是if(condition){} else{},看最全的那个构造函数: pub ...

  3. requests爬取豆瓣top250电影信息

    ''' 1.爬取豆瓣top250电影信息 - 第一页: https://movie.douban.com/top250?start=0&filter= - 第二页: https://movie ...

  4. 十三、springboot 优雅集成spring-boot-admin 实现程序监控

    前言 我们知道项目的监控是尤为重要的,但是我们如果用jdk 自带的jconsole 和jvisualvm 的话会非常繁琐,且界面不是很友好.之前我们使用了spring boot 项目,但是都没有对项目 ...

  5. 数据库中间件分片算法之stringhash

    前言 又是一个夜黑风高的晚上,带上无线耳机听一曲.突然很感慨一句话:生活就像心电图,一帆风顺就证明你挂了. 就如同我们干运维的,觉得很简单的事情,有时候能干出无限可能.还是言归正传吧,这一次我们来说说 ...

  6. $CF908D\ New\ Year\ and\ Arbitrary\ Arrangement$ 期望$dp$

    正解:期望$dp$ 解题报告: 传送门$QwQ$ 阿关于题目里那个形如$ab$的子序列我说下,,,我我我之前$get$了好久$QAQ$.这里子序列的个数的定义是这样儿的,举个$eg$,$aabb$,就 ...

  7. Java中日期格式化YYYY-DD的坑

    写这篇博文是记录下跨年的bug.去年隔壁组的小伙伴就是计算两个日期之间间隔的天数,因为跨年的原因计算有误. 当时测试组的小姐姐也没有模拟出来这种场景,导致上生产环境直接影响线上的数据. 今天逛技术论论 ...

  8. Python+appium+unittest UI自动化测试

    什么是UI自动化 自动化分层 单元自动化测试,指对软件中最小可测试单元进行检查和验证,一般需要借助单元测试框架,如java的JUnit,python的unittest等 接口自动化测试,主要检查验证模 ...

  9. HDU3555 Bomb 题解 数位DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题目大意:求 \([1,n]\) 范围内有多少数包含"49". 解题思路: ...

  10. C语言之while循环

    while循环能做什么??? 先来个概念格式,while循环的一般形式为: while(表达式){ 语句块 } 意思是,先计算"表达式"的值,当值为真(非0)时, 执行" ...