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 ...
随机推荐
- JS 浏览器地址栏传递参数,参数加密/解密(编码/解码)
我们有时候在JS里进行页面跳转,并且传递了参数(AppName),如下: window.location = "../../views/form/edit.html?AppName=新增&q ...
- java实现一个简单的验证码生成器
最近看了网上很多大佬们写的验证码生成,寻思着自己也写一个,话不多说,代码如下: import java.awt.BasicStroke; import java.awt.Color; import j ...
- Django入门------常见问题
项目启动后仅本机可访问 1.修改 Django项目中的settings.py中的 ALLOWED_HOSTS 的值为 ['*']# 准许那些地址访问,* 表示任意地址ALLOWED_HOSTS = [ ...
- Android res之shape
xml控件配置属性 android:background="@drawable/shape" 标签 corners ----------圆角gradient ----------渐 ...
- python调用系统命令的方法
1.os模块 (1)system()方法 这个方法是直接调用标准C的system() 函数,在一个子终端运行系统命令 (2)poen()方法 这个方法执行命令后通过一个管道文件将结果返回 3.subp ...
- 五十一:数据库之Flask-Migrate详解
在实际开发中,经常会发生数据库修改行为,一般数据库修改不是直接手动修改,而是去修改ORM模型,然后再把模型映射到数据库中,这些操作可以通过flask-migrate实现,flask-migrate是基 ...
- IDEA Cannot access alimaven (http://maven.aliyun.com/nexus/content/groups/public/)
[ERROR] Plugin org.apache.maven.plugins:maven-compiler-plugin:3.1 or one of its dependencies could n ...
- java源码-ReentrantLock源码分析-1
ReentrantLock 继承于lock是比较常用的独占锁,接下来我们来分析一下ReentrantLock源码以及接口设计: Sync是ReentrantLock的内部静态抽象类继承Abstract ...
- Java连接Sap系统调并调用RFC函数
参考博客:https://blog.csdn.net/qq_36026747/article/details/81287462 https://www.cnblog ...
- EUREKA 删除 or 强制下线/上线 实例
开发环境,EUREKA 注册中心 某服务被注册了多个实例,feign 调用时 服务请求到其他实例上,请求收不到,使用一下命令删除 或者强制下线实例: 1 .DELETE 删除注册实例,但是如果被删除 ...