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 ...
随机推荐
- 设置Linux自启服务以及优先级
一. 启动优先级 今天有一台服务器没有正常启动,原因是有一个服务没有启动起来,因为A服务需要B服务启动之后才能正常启动,所以需要调整A,B服务的启动顺序.在网上查找了一些资料,总结了一下,以备以后需要 ...
- 代码优化-多态代替IF条件判断
场景描述 在开发的场景中,常常会遇到打折的业务需求,每个用户对应的等级,他们的打折情况也是不一样的.例如普通会员打9折,青铜会员打8.5折,黄金会员打8折等等.在一般开发中最简单的就是判断用户的等级, ...
- SpringSecurity开发
RBAC 数据库权限表结构设计与创建 sys_user表 CREATE TABLE sysuser (id INT(10) unsigned PRIMARY KEY NOT NULL COMMENT ...
- LC 759. Employee Free Time 【lock, hard】
We are given a list schedule of employees, which represents the working time for each employee. Each ...
- javascript的历史和入门
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- android开发过程报错
Unable to start activity ComponentInfo{com.example.zxy.myapp/com.example.zxy.myapp.MainActivity}: an ...
- idea debug的drop frame,set watch和设置过滤条件
idea debug中的drop frame就是回退到上一个方法调用的开始处,在IDEA里测试无法一行一行地回退或回到到上一个断点处,而是回到上一个方法. 在调用栈方法上选择要回退的方法,右键选择Dr ...
- 基于durid的JDBCUtils工具类
1.JDBCUtils类 package com.alphajuns.utils; import com.alibaba.druid.pool.DruidDataSourceFactory; impo ...
- 使用Navicat为Oracle导入函数后函数显示红叉
上图是plsql中的截图 有可能是Navicat没有缓存过程,刷新试一试,不行的话,对导入的函数进行重新编译即可. 还发现一个问题是,Navicat导出的脚本里面,函数部分竟然没有参数和返回值,让我很 ...
- C基础知识(12):可变参数
该功能需要使用<stdarg.h>.函数的最后一个参数写成省略号,即三个点号(...),省略号之前的那个参数是int,代表了要传递的可变参数的总数.该文件提供了实现可变参数功能的函数和宏. ...