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方法。

  1,上述代码中,无论int i =1/0 这个异常出现在哪里,添加员工和添加部门都会回滚。
因为 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;
}
 关于这个属性,在以上代码中,主要是添加到addDeptBySupports上的,也就是被调用方法上。因为添加到addEmpBySupports就不以事务的方式运行了。
 然后,如果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有事务,则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;
}
 这个属性应该是除了REQUIRED用的最多的。这个属性也是针对被调用者的(addDeptByRequiresNew)。
 不管调用者(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;
}
 这个属性如果放在调用者(addEmpByNotSupported)上,则是以非事务方式运行。
 如果放在被调用者(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;
}
  可以这么理解,大多数情况下,效果和REQUIRED一样。但是有一种情况,就是上述代码中,被调用者事务传播属性为NESTED,当出现异常时, 调用者把departmentService try,catch了。这个区别与REQUIRED的并不会报错,而且addEmpByNested方法不会回滚,只有addDeptByNested回滚了。
  大概原理:当被调用者使用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的事务传播机制实例 (转)的更多相关文章

  1. spring事务传播机制实例讲解

    http://kingj.iteye.com/blog/1680350   spring事务传播机制实例讲解 博客分类:   spring java历险     天温习spring的事务处理机制,总结 ...

  2. 数据库事务的隔离以及spring的事务传播机制

    数据库的事务隔离: MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”RR(REPEATABLE READ). oracle默认的是提交读.RC 未提交读(READ UNCOMMITTE ...

  3. Spring的事务传播机制(通俗易懂)

    概述 Spring的事务传播机制有7种,在枚举Propagation中有定义. 1.REQUIRED PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就 ...

  4. 一天十道Java面试题----第五天(spring的事务传播机制------>mybatis的优缺点)

    这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 41.spring的事务传播机制 42 .spring事务什么时候会失效 43 .什么的是bean的自动装配.有哪些方式? ...

  5. spring事务中隔离级别和spring的事务传播机制

    Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一般就不做了,要么做完,要 么就不做.也就是说,事务必须是 ...

  6. Spring的事务传播机制

    1.事务传播类型     新建事务 required required_new   - 挂起当前    非事务方式运行 supports not_supported  - 挂起当前 never    ...

  7. Spring事务传播机制和数据库隔离级别

    Spring事务传播机制和数据库隔离级别 转载 2010年06月26日 10:52:00 标签: spring / 数据库 / exception / token / transactions / s ...

  8. Spring事务传播机制

    Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播,即协调已经有事务标识的方法之间的发生调用时的事务 ...

  9. spring 事务传播机制

    spring 事务 传播机制 描述的 事务方法直接相互调用,父子事物开启,挂起,回滚 等的处理方式. 绿色的 那几个 我认为比较重要. 1 , @Transactional(propagation=P ...

随机推荐

  1. ansible模块文件操作

    Ansible常用模块文件操作 [root@tiandong etc]# ansible-doc -l   列出ansible所支持的模块 [root@tiandong ~]# ansible-doc ...

  2. 设置PyCharm中选择文本的背景颜色和代码中和选中单词相同单词的背景颜色

    1 设置选中单词的背景颜色 首先进入File->Setting->Editor->Color Scheme后复制一个存在的颜色主题作为自定义的颜色主题(默认的颜色主题是无法修改的,也 ...

  3. EDM数据营销之电商篇| 六大事务性邮件,环环相扣打造极致用户体验!

    “以用户为中心”的时代,电商们致力于打造极致的用户体验,想尽各式新颖营销办法,但难免还是会出现营销断层,以至于和用户间无法达到完整的交互. 本次Focussend以邮件营销为例,聚焦用户从浏览到支付等 ...

  4. java回调函数详解

    声明:博客参考于https://www.cnblogs.com/yangmin86/p/7090882.html,谢谢哥们 回调函数:是指在A类执行代码时,调用了B类中的方法,但B类中的方法执行了A类 ...

  5. Unity和Mef的比较

    1:Mef和Untiy都支持依赖注入 2:Mef支持插件的机制 3:Mef在写法上更简单灵活 4:Mef在宏观上比Unity更加庞大 5:Mef不支持Aop的切入拦截,Unity支持

  6. flask 学习(二)

    安装了flask扩展 以及flask-bootstrap 默认情况下,flask在template文件夹寻找模板. flask 加载的是Jinja2模板,该模板引擎在flask中由函数render_t ...

  7. Linux Openssh源码升级

    telnet服务 yum install -y telnet-server xinetd systemctl start xinetd systemctl start telnet.socket #监 ...

  8. etcd三节点安全集群搭建-pki安全认证

    etcd安全集群搭建就是 pki安装认证 1.环境: 三台centos7. 主机 192.168.0.91 192.168.0.92 192.168.0.93 都关闭防火墙 都关闭selinux 配置 ...

  9. java:JQuery(Ajax,JSON)

    1.遍历ajax返回的json: 第一种: <%@ page language="java" import="java.util.*" pageEncod ...

  10. PTA --- 天梯赛 L1-064 估值一亿的AI核心代码

    L1-064 估值一亿的AI核心代码 (20 point(s)) 本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是: 无论用户说什么,首先把对方说的话在一行中原样打印出来: 消除原文中多 ...