-
2021-06-07 15:24:32
spring事务传播特性
1.Propagation.REQUIRED(spring中@Transactional默认方式)
如果当前有事务就加入当前事务,如果没有事务就新建一个事务
2.Propagation.SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式运行
3.Propagation.MANDATORY
使用当前事务,如果当前没有事务,就抛出异常
4.Propagation.REQUIRES_NEW
新建一个事务,如果当前有事务就将当前事务挂起。外部事务不会影响内部事务
5.Propagation.NESTED
新建一个事务,如果当前有事务就嵌套在当前事务内执行,否则执行与Propagation.REQUIRED类似操作
6.Propagation.NOT_SUPPORTED
非事务方式执行,如果当前有事务,就将当前事务挂起
7.Propagation.NEVER
非事务方式执行,如果当前有事务,就抛出异常常用的有Propagation.REQUIRED、Propagation.REQUIRES_NEW、Propagation.NESTED三种
三者相同与不同点:
REQUIRES_NEW内部方法事务独立于外部方法事务,所以外部方法异常回滚,内部事务不会回滚。
NESTED与REQUIRES_NEW一样具有独立的事务,子事务可不影响外部事务。但是其属于嵌套在外部事务中,所以外部事务回滚,内部事务也会回滚。更多相关内容 -
详解事务传播特性
2020-08-30 16:19:19事务传播特性汇总: required:使用当前的事务,如果当前没有事务,则创建一个事务,子方法是必须运行在一个事务中的,如果当前存在事务,则加入这个事务,成为一个整体。 supports:如果当前有事务,则使用事务,...事务传播特性汇总:
required:使用当前的事务,如果当前没有事务,则创建一个事务,子方法是必须运行在一个事务中的,如果当前存在事务,则加入这个事务,成为一个整体。
supports:如果当前有事务,则使用事务,如果当前没有事务,则不使用事务
mandatory:该传播属性强制必须存在一个事务,如果不存在,则抛出异常
required_new:如果当前有事务,则挂起该事务,并且自己创建一个新的事务给自己使用;如果当前没有事务,则同required
not_support:如果当前有事务,则把事务挂起,自己不使用事务去进行数据库操作
never:如果当前事务存在,则抛出异常
nested: 如果当前有事务,则开启子事务(嵌套事务),嵌套事务是独立提交或者回滚;如果当前没有事务,则同required
但是如果父事务提交,则会携带子事务一起提交。如果父事务回滚,则子事务会一起回滚。相反,子事务异常,则父事务可以不会滚(捕获子事务的异常),也可以回滚。
有异常才会回滚事务,如果异常被捕获,也就是try,catch,就不会回滚事务了,
发生异常,或者抛出异常都会回滚事务
准备工作
演示required
每次测试之前都会清空数据库
导入test依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
编写test类
import com.imooc.Application; import com.imooc.service.impl.TestTransService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class TransTest { @Autowired private TestTransService testTransService; /* * 事务传播特性 * required: * supports: * mandatory: * required_new: * not_supported: * never: * nested: * */ @Test public void demo(){ testTransService.saveParent(); testTransService.saveChildren(); } }
编写需要的测试方法
package com.imooc.service.impl; import com.imooc.mapper.StuMapper; import com.imooc.pojo.Stu; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TestTransService { @Autowired private StuMapper stuMapper; public void saveParent(){ Stu stu=new Stu(); stu.setName("parent"); stu.setAge(55); stuMapper.insert(stu); } public void saveChildren(){ saveChild1(); int a=1/0; saveChild2(); } public void saveChild1(){ Stu stu1=new Stu(); stu1.setName("child-1"); stu1.setAge(11); stuMapper.insert(stu1); } public void saveChild2(){ Stu stu2=new Stu(); stu2.setName("child-2"); stu2.setAge(22); stuMapper.insert(stu2); } }
没有开启事务,直接测试
报错:java.lang.ArithmeticException: / by zero
结论:在报错之前,已经执行的代码会进行数据库操作,之后代码没有执行,也就没有操作数据库
在demo()方法上开启事务,进行测试
import com.imooc.Application; import com.imooc.service.impl.TestTransService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class TransTest { @Autowired private TestTransService testTransService; /* * 事务传播特性 * required: * supports: * mandatory: * required_new: * not_supported: * never: * nested: * */ @Transactional(propagation = Propagation.REQUIRED) @Test public void demo(){ testTransService.saveParent(); testTransService.saveChildren(); } }
报错:java.lang.ArithmeticException: / by zero
结论:事务具有传播特性,demo()方法开启事务,方体体里面的方法也具有事务,所以报错后数据库进行了回滚操作
如果demo方法没有开启事务,在saveChildren()上开启了事务( @Transactional(propagation = Propagation.REQUIRED))
,则会保存saveParent()方法插入的数据。
required:使用当前的事务,如果当前没有事务,则创建一个事务,子方法是必须运行在一个事务中的,如果当前存在事务,则加入这个事务,成为一个整体。
================================================================================================
演示required_new
spring boot测试环境会自动回滚,不适合测试事务,直接使用开发环境,然后用postman调用
controller
package com.imooc.controller; import com.imooc.service.impl.TestTransService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestTransController { @Autowired private TestTransService testTransService; @PostMapping("/demo") @Transactional(propagation = Propagation.REQUIRED) public void demo()throws Exception{ testTransService.saveParent(); testTransService.saveChildren(); } }
demo()方法上面加@Transactional(propagation = Propagation.REQUIRED)
saveChildren()方法上面加@Transactional(propagation = Propagation.REQUIRES_NEW)
调用postman运行
报错:java.lang.NullPointerException: null
结论:由于抛出空指针异常,所以saveChildren()这个新事物会回滚,而抛出的异常会传递给父方法,父方法的事务也会回滚,所有没有一条记录
另外一种情况
saveChildren()
@Transactional(propagation = Propagation.REQUIRES_NEW) public void saveChildren(){ saveChild1(); /*String demon=null; System.out.println(demon.charAt(0));*/ saveChild2(); }
demo()
@PostMapping("/demo") @Transactional(propagation = Propagation.REQUIRED) public void demo(){ testTransService.saveParent(); testTransService.saveChildren(); String demon=null; System.out.println(demon.charAt(0)); }
调用postman
报错:java.lang.NullPointerException: null
结论:可以证明required_new创建的时新事务
================================================================================================
演示nested
saveChildren
@Transactional(propagation = Propagation.NESTED) public void saveChildren(){ saveChild1(); saveChild2(); }
demo
@PostMapping("/demo") @Transactional(propagation = Propagation.REQUIRED) public void demo(){ testTransService.saveParent(); testTransService.saveChildren(); String demon=null; System.out.println(demon.charAt(0)); }
调用postman
报错是一定的:java.lang.NullPointerException: null
结论:父事务回滚,子事务也一起回滚
另外一种情况
demo
@PostMapping("/demo") @Transactional(propagation = Propagation.REQUIRED) public void demo(){ testTransService.saveParent(); testTransService.saveChildren(); }
saveChildren
@Transactional(propagation = Propagation.NESTED) public void saveChildren(){ saveChild1(); String demon=null; System.out.println(demon.charAt(0)); saveChild2(); }
万年不变报错:java.lang.NullPointerException: null
结论:子事务异常,父事务没有捕获异常,则一起回滚
另外一种情况
saveChildren
@Transactional(propagation = Propagation.NESTED) public void saveChildren(){ saveChild1(); String demon=null; System.out.println(demon.charAt(0)); saveChild2(); }
demo
@PostMapping("/demo") @Transactional(propagation = Propagation.REQUIRED) public void demo(){ testTransService.saveParent(); try { //相当于数据库中的savepoint 捕获异常之后,不影响其他事务操作 testTransService.saveChildren(); } catch (Exception e) { e.printStackTrace(); } }
调用postman:
报错:java.lang.NullPointerException
结论:捕获子事务异常之后,父事务不需要回滚,子事务进行回滚
-
Spring 的事务传播特性和隔离级别
2022-03-20 14:42:46spring事务的传播级别 PROPAGATION_REQUIRED:Spring的默认传播级别,如果上下文中存在事务则加入当前事务,如果不存在事务则新建事务执行。 PROPAGATION_SUPPORTS:如果上下文中存在事务则加入当前事务,如果没有...spring事务的传播级别
PROPAGATION_REQUIRED:Spring的默认传播级别,如果上下文中存在事务则加入当前事务,如果不存在事务则新建事务执行。
PROPAGATION_SUPPORTS:如果上下文中存在事务则加入当前事务,如果没有事务则以非事务方式执行。
PROPAGATION_MANDATORY:该传播级别要求上下文中必须存在事务,否则抛出异常。
PROPAGATION_REQUIRES_NEW:该传播级别每次执行都会创建新事务,并同时将上下文中的事务挂起,执行完当前线程后再恢复上下文中事务。(子事务的执行结果不影响父事务的执行和回滚)
PROPAGATION_NOT_SUPPORTED:当上下文中有事务则挂起当前事务,执行完当前逻辑后再恢复上下文事务。(降低事务大小,将非核心的执行逻辑包裹执行。)
PROPAGATION_NEVER:该传播级别要求上下文中不能存在事务,否则抛出异常。
PROPAGATION_NESTED:嵌套事务,如果上下文中存在事务则嵌套执行,如果不存在则新建事务。(save point概念)事务隔离级别
脏读:读取到了别的事务回滚前的数据,例如B事务修改数据库X,在未提交前A事务读取了X的值,而B事务发生了回滚。
不可重复读:一个事务在两次读取同一个数据的值不一致。例如A事务读取X,在中间过程中B事务修改了X的值,事务A再次读取X时值发生了改变。
幻读:查询得到的数据条数发生了改变,例如A事务搜索数据时有10条数据,在这时B事务插入了一条数据,A事务再搜索时发现数据有11条了。
数据隔离级别
read-uncommitted:未提交读(脏读、不可重复读、幻读)
read-committed:已提交读(不可重复读、幻读),大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。
repeatable-read:可重复读(幻读),保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。
serializable:串行化最严格的级别,事务串行执行,资源消耗最大Spring事务传播和隔离级别配置
@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,timeout=1,isolation=Isolation.DEFAULT)
事务的传播性:@Transactional(propagation=Propagation.REQUIRED) 如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
事务的超时性:@Transactional(timeout=30) //默认是30秒
事务的隔离级别:@Transactional(isolation = Isolation.READ_UNCOMMITTED)
回滚指定异常类:@Transactional(rollbackFor={RuntimeException.class,
Exception.class})
只读:@Transactional(readOnly=true)该属性用于设置当前事务是否为只读事务,设置为true表示只读 -
Spring的事务传播特性
2020-11-18 19:50:19Spring的事务传播特性 1、Spring的事务传播特性 事务属性的种类:传播行为、隔离级别、只读和事务超时。 事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。 2、Spring事务传播行为种类 spring...Spring的事务传播特性
1、Spring的事务传播特性
事务属性的种类:传播行为、隔离级别、只读和事务超时。
事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。
2、Spring事务传播行为种类
spring支持7种事务传播行为,分别为:
propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作。
3、说明
Spring 默认的事务传播行为是 PROPAGATION_REQUIRED,它适合于绝大多数的情况。假设 ServiveY#methodY() 都工作在事务环境下(即都被 Spring 事务增强了),假设程序中存在如下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么这 3 个服务类的 3 个方法通过 Spring 的事务传播机制都工作在同一个事务中。
-
spring事务传播特性与内部事务回滚问题
2021-09-24 21:43:41spring事务传播特性与内部事务回滚问题 前提:同一个类,内部方法调用不走代理,spring基于注解的事务是基于代理的,不走代理,被调用的方法就不受事务管理代码的控制。 原理: 1、<bean id=... -
Spring事务传播特性实例解析
2020-10-25 12:03:14Spring事务传播特性实例解析 背景介绍 目前系统正在进行代码重构前期预研工作,目标采用spring控制事务以减少开发代码量,提高开发效率。同时避免开发人员编码控制事务所带来的链接没有释放,事务没有提交,出现... -
SpringBoot事务传播特性,就这么点事儿!
2020-04-09 15:43:10情景一:A方法 未添加 事务注解,B方法事务的propagation=Propagation.NEVER 执行结果:A、B均新增成功,B抛出RuntimeException。 情景二:A方法 添加了 事务注解,B方法事务的propagation=Propagation.NEVER ... -
Spring事务传播特性解析
2013-11-05 01:00:43通过代码解析spring传播特性,包括 1、Propagation.REQUIRED 方法被调用时自动开启事务,在事务范围内使用则使用同一个事务,否则开启新事务。 2、Propagation.REQUIRES_NEW 无论何时自身都会开启事务 3、... -
Spring事务传播特性的最好总结和面试答案
2019-11-30 17:39:23Spring事务传播特性一共有7种: 1. REQUIRED 代表如果已经存在一个事务,就加入到这个事务中。如果当前没有事务,就新建一个事务,就是默认的事务传播设置。 类比解释:如果马路上面有车就搭车,没有车就自己造一... -
@Transactional 事务传播特性——简单易懂
2021-08-03 16:14:47事务的默认传播类型是PROPAGATION_REQUIRED 点击进REQUIRED查看源码可以发现上方的注释说明:不存在事务则创建一个新事务 REQUIED:使用当前事务,如果当前没有事务,则自己新建一个事务,子方法是必须运行... -
讲讲Spring事务传播特性?
2020-04-19 01:30:13事务:一起成功,一起失败. 小明转账给小红1000元: 小明账户扣除1000 小红账户增加1000 转账事务要么成功,要么失败. 事务隔离级别: 读未提交 读已提交 可重复读 序列化 事务没有隔离出现的并发问题: 脏读: 一个... -
Spring中的事务传播特性
2019-10-24 10:40:00事务的传播特性可以通过@Transactional的propagation属性指定 例: @Transactional(propagation=Propagation.REUIRED) REQUIRED:默认的传播特性,业务方法需要在一个事务中运行,如果一个方法处在事务中那么就... -
Spring的7大事务传播特性
2020-07-31 11:27:55Spring事务传播特性概述 传播特性:解决事务在方法之间如何传播:是共用父事务,还是一个有一个没有,还是父子事务分别进行!! propagation_XXX 我的理解 官方 PROPAGATION_REQUIRED 子事务共用父事务,谁... -
Spring 事务传播特性和隔离级别
2020-02-28 10:18:49Spring 事务传播特性和隔离级别 事务是处理逻辑原子性的保证,作为单个逻辑单元执行一系列操作,要么执行完成要么全部不执行。事务遵循ACID四个特性。 事务的两个重要特性是,事务的传播特性和事务的隔离级别特性。... -
SpringBoot中事务传播特性的使用
2020-07-20 17:28:43REQUIRED : 使用当前的事务 ,...MANDATORY : 该传播属性强制必须存在一个事务 ,如果不存在,则抛出异常 REQUIRES_NEW : 如果当前有事务 ,则挂起事务 ,并且自己创建一个新的事务给自己使用; 如果当前没有事务 , 则同requi -
spring中事务传播特性,REQUIRED/REQUIRES_NEW/NESTED
2020-04-21 20:39:46spring中事务传播特性,REQUIRED/REQUIRES_NEW/NESTED结论当前方法跟被调用方法不在同一个类中时当前方法跟被调用方法在同一个类中时验证验证代码验证过程不同类调用时同一个类调用时 结论 当前方法跟被调用方法不在... -
Spring~事务API、事务失效原因、事务传播特性
2021-02-27 21:34:55文章目录Spring事务事务API实现原理事务失效事务传播机制 Spring事务 Spring事务是在所使用的数据库事务的基础上进行封装扩展 封装主要是封装了一些JDBC的一写事务操作的对象, 扩展主要有以下几点特性 加入了事务... -
Spring Boot 事务传播特性
2021-06-24 17:39:57Spring Boot 事务的传播特性指的是:方法 A 内部调用了方法 B,且二者都有 @Transaction 注解,此时事务该怎么处理? // A 方法 @Transactional public void externalMethod() throws Exception { userRepository.... -
什么是事务的传播特性?
2021-02-02 11:01:08我们都知道事务的概念,那么事务的传播特性是什么呢?(此处着重介绍传播特性的概念,关于传播特性的相关配置就不介绍了,可以查看spring的官方文档)在我们用SSH开发项目的时候,我们一般都是将事务设置在Service层 ... -
spring事务传播特性和事务隔离级别
2015-04-24 10:49:32一、事务传播特性 转自:http://www.iteye.com/topic/35907 在所有使用 spring 的应用中, 声明式事务管理可能是使用率最高的功能了, 但是, 从我观察到的情况看, 绝大多数人并不能深刻理解事务声明中不同事务传播... -
Spring控制Hibernate中的事务传播特性与隔离级别操作.docx
2019-11-20 15:28:06Spring控制Hibernate中的事务传播特性与隔离级别操作,通过利用spring和Hibernate的两个HibernateTemplate 和 jdbcTemplate类,实现数据的交互。 -
事务传播特性&事务隔离级别
2013-07-23 10:36:29java事务传播特性&事务隔离级别... -
解惑spring事务传播特性之嵌套事务
2017-09-14 10:35:47在所有使用 spring 的应用中, 声明式事务管理可能是使用率最高的功能了, 但是, 从我观察到的情况看, 绝大多数人并不能深刻理解事务声明中不同事务传播属性配置的的含义, 让我们来看一下 TransactionDefinition ... -
spring事务的传播特性
2021-02-26 17:54:15java事务传播特性共分为7种,默认的是REQUIREDREQUIRED(0),SUPPORTS(1),MANDATORY(2),REQUIRES_NEW(3),NOT_SUPPORTED(4),NEVER(5),NESTED(6);【REQUIRED】service1:事务传播机制:REQUIREDservice2:事务传播机制:... -
事务传播特性了解事务的几种传播特性
2011-09-21 20:13:30事务传播特性了解事务的几种传播特性 总共有七种propagation——required propagation——support propagation——mandatory propagation——not——supported propagation_required_new propagation_never ... -
spring事务传播特性实现原理
2016-06-27 23:30:10配置spring事务,需要在配置文件中配置,通过spring的Aop,会执行到AbstractPlatformTransactionManager的getTransaction方法 public final TransactionStatus getTransaction(TransactionDefinition definition...