Spring的事务传播机制实例 (转)
1,Propagation.REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。详细解释在代码下方。
实例
员工service
@Service
public class EmployeeServiceImpl implements EmployeeService { @Autowired
EmployeeMapper employeeMapper; @Autowired
DepartmentService departmentService; /**
* 添加员工的同时添加部门
* REQUIRED 传播
* @param name 员工姓名
*/
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addEmpByRequired(String name) {
Employee employee = new Employee();
employee.setDeptId(1);
employee.setName(name);
employee.setAddress("邯郸");
employeeMapper.insertSelective(employee);
departmentService.addDept("jishubu");
int i = 1/0;
}
}
部门service
@Service
public class DepartmentServiceImpl implements DepartmentService { @Autowired
DepartmentMapper departmentMapper; @Override
public void addDeptByRequired(String name) {
Department department = new Department();
department.setName(name);
departmentMapper.insertSelective(department);
// int i = 1/0;
}
}
注:该篇文章所测试的皆是运行addEmpByRequired方法。
因为 REQUIRED 会让添加员工和添加部门变为一个事务。
2,值得一提的是,如果异常在addDept中,但是在addEmpByRequired把 addDept方法 try,catch了,则会抛出异常:Transaction rolled back because it has been marked as rollback-only 。
3,如果在addDeptByRequired上添加@Transactional(propagation = Propagation.REQUIRED),在addEmpByRequired不添加事务,则addDeptByRequired是一个事务,addEmpByRequired并不是一个事务。因为addDeptByRequired开启了一个事务,但是addEmpByRequired并不存在一个事务中。
2,Propagation.SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
实例
员工service
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addEmpBySupports(String name) {
Employee employee = new Employee();
employee.setDeptId(2);
employee.setName(name);
employee.setAddress("邯郸");
employeeMapper.insertSelective(employee);
departmentService.addDeptBySupports("jishubu");
// int i = 1/0;
}
部门Service
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public void addDeptBySupports(String name) {
Department department = new Department();
department.setName(name);
departmentMapper.insertSelective(department);
int i = 1/0;
}
然后,如果addEmpBySupports为事务,则addDeptBySupports也为事务。如果addEmpBySupports不是事务,则addDeptBySupports也不是事务。
3,Propagation.MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
员工Service
@Override
// @Transactional(propagation = Propagation.REQUIRED)
public void addEmpByMandatory(String name) {
System.out.println("aaaaaa");
Employee employee = new Employee();
employee.setDeptId(3);
employee.setName(name);
employee.setAddress("邯郸");
employeeMapper.insertSelective(employee);
departmentService.addDeptByMandatory("jishubu");
int i = 1/0;
}
部门Service
@Override
@Transactional(propagation = Propagation.MANDATORY)
public void addDeptByMandatory(String name) {
Department department = new Department();
department.setName(name);
departmentMapper.insertSelective(department);
int i = 1/0;
}
该属性添加到addDeptByMandatory上, 如果addEmpByMandatory有事务,则addDeptByMandatory加入到addEmpByMandatory的事务中,如果addEmpByMandatory没有事务,则直接抛出异常。
4,Propagation.REQUIRES_NEW
员工Service
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addEmpByRequiresNew(String name) {
Employee employee = new Employee();
employee.setDeptId(4);
employee.setName(name);
employee.setAddress("邯郸");
employeeMapper.insertSelective(employee);
departmentService.addDeptByRequiresNew("jishubu");
int i = 1/0;
}
部门Service
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addDeptByRequiresNew(String name) {
Department department = new Department();
department.setName(name);
departmentMapper.insertSelective(department);
// int i = 1/0;
}
不管调用者(addEmpByRequiresNew)是否存在事务,被调用者(addDeptByRequiresNew)都会新开一个事务,相当于被调用者都存在于自己的事务中和调用者没有关系。
如上述代码,addEmpByRequiresNew会回滚,但addDeptByRequiresNew不会回滚。因为他们是两个事务。
5,Propagation.NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
员工Service
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addEmpByNotSupported(String name) {
Employee employee = new Employee();
employee.setDeptId(5);
employee.setName(name);
employee.setAddress("邯郸");
employeeMapper.insertSelective(employee);
departmentService.addDeptByNotSupported("jishubu");
int i = 1/0;
}
部门Service
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void addDeptByNotSupported(String name) {
Department department = new Department();
department.setName(name);
departmentMapper.insertSelective(department);
int i = 1/0;
}
如果放在被调用者(addDeptByNotSupported)上,该方法(addDeptByNotSupported)以非事务运行,调用者如果有事务,则运行单独的事务(挂起)。
上述代码,会出现添加员工回滚,添加部门不回滚。
6,Propagation.NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
员工Service
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addEmpByNever(String name) {
Employee employee = new Employee();
employee.setDeptId(6);
employee.setName(name);
employee.setAddress("邯郸");
employeeMapper.insertSelective(employee);
departmentService.addDeptByNever("jishubu");
int i = 1/0;
}
部门Service
@Override
@Transactional(propagation = Propagation.NEVER)
public void addDeptByNever(String name) {
Department department = new Department();
department.setName(name);
departmentMapper.insertSelective(department);
int i = 1/0;
}
上述代码中,则会抛出异常。(并不是除0异常,而是:Existing transaction found for transaction marked with propagation 'never')
7,Propagation.NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。(这个和REQUIRED区别在于一个是加入到一个事务,一个是在嵌套事务运行)
员工Service
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addEmpByNested(String name) {
Employee employee = new Employee();
employee.setDeptId(7);
employee.setName(name);
employee.setAddress("邯郸");
employeeMapper.insertSelective(employee);
try { departmentService.addDeptByNested("jishubu");
}catch (Exception e){ }
// int i = 1/0;
}
部门Service
@Override
@Transactional(propagation = Propagation.NESTED)
public void addDeptByNested(String name) {
Department department = new Department();
department.setName(name);
departmentMapper.insertSelective(department);
int i = 1/0;
}
大概原理:当被调用者使用PROPAGATION_NESTED时,底层的数据源必须基于JDBC 3.0,并且实现者需要支持保存点事务机制。按上述代码来说(去掉try,catch),当执行到addDeptByNested这个方法时,Spring会为它创建一个内部的嵌套事务,如果addDeptByNested执行失败,则事务回滚到addDeptByNested之前的点,此时如果不抛异常,则不会回滚。这个嵌套事务,是addEmpByNested的一部分,只有外层事务提交了,内层的嵌套事务才会一起提交,这也是与REQUIRED(加入事务),REQUIRES_NEW(开启新事务)的区别。
还值得一提的是,NESTED是嵌套的意思,其实并不是只有NESTED用于嵌套,只要理解上述7个传播机制的意思,都可以嵌套用。
出处: https://www.jianshu.com/p/25c8e5a35ece
Spring的事务传播机制实例 (转)的更多相关文章
- spring事务传播机制实例讲解
http://kingj.iteye.com/blog/1680350 spring事务传播机制实例讲解 博客分类: spring java历险 天温习spring的事务处理机制,总结 ...
- 数据库事务的隔离以及spring的事务传播机制
数据库的事务隔离: MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”RR(REPEATABLE READ). oracle默认的是提交读.RC 未提交读(READ UNCOMMITTE ...
- Spring的事务传播机制(通俗易懂)
概述 Spring的事务传播机制有7种,在枚举Propagation中有定义. 1.REQUIRED PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就 ...
- 一天十道Java面试题----第五天(spring的事务传播机制------>mybatis的优缺点)
这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 41.spring的事务传播机制 42 .spring事务什么时候会失效 43 .什么的是bean的自动装配.有哪些方式? ...
- spring事务中隔离级别和spring的事务传播机制
Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一般就不做了,要么做完,要 么就不做.也就是说,事务必须是 ...
- Spring的事务传播机制
1.事务传播类型 新建事务 required required_new - 挂起当前 非事务方式运行 supports not_supported - 挂起当前 never ...
- Spring事务传播机制和数据库隔离级别
Spring事务传播机制和数据库隔离级别 转载 2010年06月26日 10:52:00 标签: spring / 数据库 / exception / token / transactions / s ...
- Spring事务传播机制
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播,即协调已经有事务标识的方法之间的发生调用时的事务 ...
- spring 事务传播机制
spring 事务 传播机制 描述的 事务方法直接相互调用,父子事物开启,挂起,回滚 等的处理方式. 绿色的 那几个 我认为比较重要. 1 , @Transactional(propagation=P ...
随机推荐
- JavaWeb_(Struts2框架)参数传递之接收参数与传递参数
此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...
- C# WebServices 客户端服务端
一.编写一个WebService 开发环境:VS2012 1.编写webservice阶段 打开VS2012,新建一个空的web应用程序,我这里用的Framework版本是4.5的 新建好web应用程 ...
- 前世今生:Hive、Shark、spark SQL
Hive (http://en.wikipedia.org/wiki/Apache_Hive )(非严格的原文顺序翻译) Apache Hive是一个构建在Hadoop上的数据仓库框架,它提供数据的 ...
- 转载:一文详解SQL解析与应用
转载地址:http://www.elecfans.com/emb/20180618696111.html 数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严 ...
- Oracle 12C 物理Standby 主备切换switchover
Oracle 12C 物理Standby 主备切换switchover Oracle 12C 物理Standby 主备切换switchover Table of Contents 1. 简述 2. 切 ...
- pandas之数据处理操作
1.pandas对缺失数据的处理 我们的数据缺失通常有两种情况: 1.一种就是空,None等,在pandas是NaN(和np.nan一样) 解决方法: 判断数据是否为NaN:pd.isnull(df) ...
- java:redis(redis安装配置,redis的伪集群配置)
1.redis安装配置: .安装gcc : yum install gcc-c++ .使用FTP工具FileZilla上传redis安装包到linux根目录下(当前步骤可以替换为:在root目录下执行 ...
- spring-boot集成5:集成jrebel实现热加载
Why Jrebel? 使用jrebel可以方便的实现spring-boot项目的热部署,直接reload更改的class,无需重启,提升开发效率. 1.安装jrebel插件 在idea中安装jreb ...
- 2019CVPR:Classification-Reconstruction Learning for Open-Set Recogition(Abstract)
Abstract Open-set classification is a problem of handling 'unknown' classes that are not contained i ...
- JavaScript基础之数组常用方法
目录 JS 数组常用API 常用属性 常用方法 常见方法语法解释 from方法 isArray concat every fill filter find forEach indexOf join k ...