Spring事务梳理
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事务梳理的更多相关文章
- 【面试】足够应付面试的Spring事务源码阅读梳理(建议珍藏)
Starting from a joke 问:把大象放冰箱里,分几步? 答:三步啊,第一.把冰箱门打开,第二.把大象放进去,第三.把冰箱门带上. 问:实现Spring事务,分几步? 答:三步啊,第一. ...
- spring事务详解(五)总结提高
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.概念 ...
- spring 事务源码赏析(二)
我们在spring 事务源码赏析(一) 中分析了spring事务是如何找到目标方法,并如何将事务的逻辑织入到我们的业务逻辑中.本篇我们将会看到spring事务的核心实现: 1.事务传播机制的实现 2. ...
- Spring事务专题(五)聊聊Spring事务到底是如何实现的
前言 本专题大纲: 本文为本专题倒数第二篇文章. 在上篇文章中我们一起学习了Spring中的事务抽象机制以及动手模拟了一下Spring中的事务管理机制,那么本文我们就通过源码来分析一下Spring中的 ...
- spring事务:事务控制方式,使用AOP控制事务,七种事务传播行为,声明事务,模板对象,模板对象原理分析
知识点梳理 课堂讲义 1)事务回顾 1.1)什么是事务-视频01 事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败. 1.2)事务的作用 事务特征(ACID) 原子 ...
- spring事务概念理解
1.数据并发问题 脏读 A事务读取B事务尚未提交的更新数据,并在此数据的基础上操作.如果B事务回滚,则A事务读取的数据就是错误的.即读取了脏数据或者错误数据. 不可重复组 A事务先后读取了B事务提交[ ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- Spring事务
1.@Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.@Transactional 的 ...
- spring事务管理器设计思想(二)
上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务.这是最常见 ...
随机推荐
- CentOS6.5升级NTP
二.安装依赖包 yum -y install gcc libcap libcap-devel glibc-devel 三.升级Ntp 1.tar zxf /tmp/ntp-4.2.8p10.tar.g ...
- Java并发编程系列-(9) JDK 8/9/10中的并发
9.1 CompletableFuture CompletableFuture是JDK 8中引入的工具类,实现了Future接口,对以往的FutureTask的功能进行了增强. 手动设置完成状态 Co ...
- 聊聊Python中的描述符
描述符是实现描述符协议方法的Python对象,当将其作为其他对象的属性进行访问时,该描述符使您能够创建具有特殊行为的对象. 通常,描述符是具有“绑定行为”的对象属性,其属性访问已被描述符协议中的方法所 ...
- jetbrains全家桶 你懂得
这个是松哥说的引用一下: 昨天一直在忙,中午抽空瞅了一眼技术群,天呐,竟然都在切磋 IDEA 激活码的事情,瞬间明白可能 jetbrains 又在搞事情了. 我大概了解了下,这次出事的主要是 2019 ...
- Linux开发环境及应用—《第三周单元测验》《第四周单元测验》
三单元 1.vi处于文本输入状态时,按下下列哪个按键可以返回命令状态?C A.^ B.$ C.Esc D- 2.vi处于命令状态时,按下下列哪组按键可以把正在编辑的内容保存到磁盘上?D A.Ctrl- ...
- Intellij IDEA 导入eclipse 项目
HoJe一个会rep的程序猿 . 感谢2019 时间匆匆,一转眼2019要跟我们说再见了.我们怀有太多的期望就难免遭遇失望和挫折.我们遇到了困难,往往不是想办法去解决,而是抱怨这个命运的不公.如果生活 ...
- 数据库中间件分片算法之enum
前言 最近挺焦虑的,不知道未来该做什么,方向又是什么.只能用别慌,月亮也正在大海的某处迷茫.来安慰下自己.不过学习的初心咱们还是不要忘记.今天我们学习的是enum分片算法. 1.hash分区算法 2. ...
- SpringBoot集成Mybatis动态多数据源后,MybatisPlus的IPage失效的问题解决方案
背景 之前做数据抽取的时候,搭了一个mybatis动态数据源切换的架子.方便他们写抽取的代码.今天同事问我,架子里面的mybatisplus的IPage失效了是什么问题.想了一下,应该是写动态数据源的 ...
- 用ES5实现ES6的数组方法map
先举个常见的栗子: var arr = [1,2,3,4,6,7,8,9,12,3,25,63,100] var arr2 = arr.map(item => item += 1) consol ...
- 【转】ArcGIS ADF 实时轨迹问题初步解决方案
Web ADF 实时轨迹是指在Web客户端指定一资源项,并对资源项进行实进跟踪并绘制出轨迹图.实时绘制可采用Ajax实现服务端与客户端无刷新动态绘制,在.net2.0 框架下可轻易实现:通过客户端时钟 ...