通过这篇文章,你将学习到Spring框架中中事务的传递

简介

在处理Spring管理的事务时,开发人员可以以传播的方式定义事务的行为。换句话说,开发人员能够决定业务方法如何被封装在逻辑和物理事务中。来自不同Spring bean的不同方法可以在相同的事务范围或分割为多个嵌套的事务中执行。这可能导致像内部事务产生的结果如何影响外部事务的细节。我们将在下一节中看到Spring中不同的传播机制的不同行为。

本教程将仅关注事务的传播机制行为。Spring事务的其他方面的细节,你可以参考其他的教程或Spring官方文档。

本教程所使用的完整代码可以在教程的下方下载。我们将仅显示Spring中帮助大家了解事务传播机制相关部分。

完整的源代码使用Hibernate实现持久层(Spring使用Hibernate的事务示例)。

表1事务传播行为类型

事务传播行为类型

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

REQUIRED行为

Spring的REQUIRED行为意味着如果在当前bean方法执行的上下文中已存在打开的事务,则使用该事务;如果没有已存在的事务,则Spring容器会创建新的事务并使用它。如果多个方法均配置为REQUIRED且调用为嵌套调用,那么它们会被划分为多个逻辑的事务,但在底层使用相同物理事务。简单来说,这意味着如果内层的方法引起了事务回滚,则外部的方法调用事务也会失败同时回滚。让我们看看一个示例:

外部Bean 

@Autowired
private TestDAO testDAO;
@Autowired
private InnerBean innerBean;
@Override @Transactional(propagation=Propagation.REQUIRED) public void testRequired(User user) { testDAO.insertUser(user); try{ innerBean.testRequired(); } catch(RuntimeException e){ // handle exception } } 内部Bean @Override @Transactional(propagation=Propagation.REQUIRED) public void testRequired() { throw new RuntimeException("Rollback this transaction!"); }

注意内部bean的方法使用了REQUIRED进行了注解并抛出了RuntimeException。这意味着它将于外部bean使用相同的事务,因此外部事务在提交时将失败并同样进行回滚操作。

注意:默认情况下,只有非受检异常(unchecked exception),像RuntimeException,会将事务的状态设置为回滚。如果你希望受检异常(checked exception)也可以将事务状态设置为回滚,你必须设置它们,但此内部不包含在本教程中。

注意2:当使用声明式事务时(也就是通过使用注解形式),如果在相同的bean中直接调用方法(自己调用自己的方法),@Transactional注解将被容器忽略。如果你希望启用自身方法调用的事务管理,你必须使用aspectj来配置事务,但是该内容不包含在本教程中。

REQUIRES_NEW行为

REQUIRES_NEW行为意味着容器将总会创建新的物理的事务,如果当前存在事务,把当前事务挂起。

外部 bean

@Autowired

private TestDAO testDAO;

@Autowired

private InnerBean innerBean;

@Override

@Transactional(propagation=Propagation.REQUIRED)

public void testRequiresNew(User user) {

  testDAO.insertUser(user);

  try{

    innerBean.testRequiresNew();

  } catch(RuntimeException e){

    // handle exception

  }

} 内部 bean

@Override

@Transactional(propagation=Propagation.REQUIRES_NEW)

public void testRequiresNew() {

  throw new RuntimeException("Rollback this transaction!");

}

内部方法使用REQUIREDS_NEW进行注解,并抛出RuntimeException,因此它的事务会回滚但是不会影响到外部的事务。外部事务在内部事务启动时将被挂起然后在内部事务处理完毕后恢复。它们独立的进行处理因此外部的事务也会成功的提交。

 NETSTED行为

NESTED行为使用相同的物理事务但是在嵌套调用时设置了保留点(savepoint),因此内部的事务可以独立于外部事务回滚而不影响外部事务。这个可能与JDBC的savepoint比较类似,因此该行为需要与Spring的JDBC管理的事务一起使用(Spring JDBC 事务例子).

 MANDATORY行为

MANDATORY行为要求执行该方法时,必须有一个已存在且打开的事务。如果没有已存在的事务,容器会抛出异常。

 NEVER行为

NEVER行为要求执行该方法时,不能有已存在的事务。如果事务已存在,那么容器将会抛出异常。

NOT_SUPPORTED行为

NOT_SUPPORTED行为标示在执行方法时,将忽略事务。如果已存在打开的事务,则该事务会被挂起。

SUPPORTS行为

SUPPORTS行为标示在执行方法时,如果存在事务,则在事务范围执行,如果不存在,则不以事务方式执行。

完整的笔记源码

本页尾有完整的代码下载。下面是 MySQL 建表语句:

MySQL 建表语句

CREATE TABLE USER (

  ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

  USERNAME VARCHAR (32) NOT NULL,

  NAME VARCHAR (64) NOT NULL,

  UNIQUE (USERNAME)

);

下载本教程源码

下载链接:   spring-transaction-propagation-tutorial.zip

相关:

事务的传播行为(讲得比较好

Spring 事务传递教程_有实例的更多相关文章

  1. Spring事务管理(详解+实例)

    1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是 ...

  2. spring事务管理(详解和实例)

    原文地址: 参考地址:https://blog.csdn.net/yuanlaishini2010/article/details/45792069 写这篇博客之前我首先读了<Spring in ...

  3. (转)Spring事务管理(详解+实例)

    文章转自:http://blog.csdn.net/trigl/article/details/50968079 写这篇博客之前我首先读了<Spring in action>,之后在网上看 ...

  4. Spring事务传递

    2018-09-25 @Transactional(propagation=Propagation.NEVER) public void update(){ Session s = sessionFa ...

  5. Spring事务管理要点总结

    # Spring事务管理要点总结 ### 要点---- 事务是企业级应用中必不可缺少的技术,用来确保数据的完整性和一致性.- Spring事务管理并不实现事务管理的实现,而是借助Hibernate\J ...

  6. SpringBoot系列教程之事务传递属性

    200202-SpringBoot系列教程之事务传递属性 对于mysql而言,关于事务的主要知识点可能几种在隔离级别上:在Spring体系中,使用事务的时候,还有一个知识点事务的传递属性同样重要,本文 ...

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

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

  8. spring 默认情况下事务是惟一的 同一个方法里面第一个sql开启后 在执行完 将事务传递给下一个sql

    spring 默认情况下事务是惟一的 同一个方法里面第一个sql开启后 在执行完 将事务传递给下一个sql

  9. spring事务详解(二)实例

    在Spring中,事务有两种实现方式: 编程式事务管理: 编程式事务管理使用底层源码可实现更细粒度的事务控制.spring推荐使用TransactionTemplate,典型的模板模式. 申明式事务管 ...

随机推荐

  1. 优先队列priority_queue的比较函数

    STL头文件:#include<queue> 优先队列: 默认从大到小排列:priority_queuee<node>q; 自定义优先级的三种方法: 1.重载操作符: bool ...

  2. [日常训练]FJ省夏令营day1

    T1 Description 给出n个矩形的顶点坐标(每个矩形的底边都在x轴上),求这n个矩形所组成图形的轮廓线的顶点. Input 第一行一个整数n,表示矩形个数. 以下n行,每行3个整数,分别表示 ...

  3. Java并发和多线程(二)Executor框架

    Executor框架 1.Task?Thread? 很多人在学习多线程这部分知识的时候,容易搞混两个概念:任务(task)和线程(thread). 并发编程可以使我们的程序可以划分为多个分离的.独立运 ...

  4. BZOJ1853 [Scoi2010]幸运数字

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  5. 加州大学伯克利分校Stat2.3x Inference 统计推断学习笔记: Section 5 Window to a Wider World

    Stat2.3x Inference(统计推断)课程由加州大学伯克利分校(University of California, Berkeley)于2014年在edX平台讲授. PDF笔记下载(Acad ...

  6. 分布式服务框架Zookeeper

    协议介绍 zookeeper协议分为两种模式 崩溃恢复模式和消息广播模式 崩溃恢复协议是在集群中所选举的leader 宕机或者关闭 等现象出现 follower重新进行选举出新的leader 同时集群 ...

  7. 【Alpha版本】 第四天 11.10

    一.站立式会议照片: 二.项目燃尽图: 三.项目进展: 成 员 昨天完成任务 今天完成任务 明天要做任务 问题困难 心得体会 胡泽善 填写招聘时用户填写各个日期到可以使用工具方便选择日期的修改 完成了 ...

  8. RMQ模板

    RMQ:范围最小值问题.给出一个n个元素的数组A1,A2,...,An,设计一个数据结构支持查询操作Query(L,R):计算min{AL,AL+1,...,AR}. 每次用一个循环来求最小值显然不够 ...

  9. 修改MySQL的默认数据存储引擎

    因为MySQL默认的是MyISAM数据引擎,不支持事务也不支持外键,所以需要用到Innodb引擎,于是决定将mysql的默认引擎设置为innodb.1 . 查看MySQL存储引擎是用的哪个?登录MyS ...

  10. 【原】React中,map出来的元素添加事件无法使用

    在使用react中,经常用到react的map函数,用法和jquery里中的map一样,但是,如果你在每个map出来的元素中添加,你会发觉添加的事件无法关联, 比如,我们很多的评论,我需要在每个评论下 ...