通过这篇文章,你将学习到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. svn服务器无法访问时检查几个文件:

    出现该问题基本都是三个配置文件的问题,下面把这个文件列出来. svnserve.conf:[general]anon-access = readauth-access = writepassword- ...

  2. 绘制图形与3D增强技巧(四)----多边形图元及其点画模式

    1.四边形图元 glBegin(GL_QUADS); glend(); 2.通用多边形 glBegin(GL_POLYGONS); glend(); 3.多边形点画模式 glenable(GL_POL ...

  3. OPENGL——背面剔除

    Opengl 表面剔除是提高 Opengl 程序渲染效率的一个有效途径. 我们知道,OpenGL 渲染的基本单位是一个个的三角形面片.无论多么复杂的3D 模 型都是由一个个基本的三角型的面片组成的. ...

  4. 小记-虚拟机装ubuntu遇到问题

    今天用虚拟机virtualbox装ubuntu遇到了一个问题,如图 解决方法: 1.首先查看创建虚拟机的时候是基本设置有没有对:(如图) 主要去看所选择的版本对应是否正确,比如32位和64位之类的. ...

  5. [bzoj1911][Apio2010]特别行动队

    Description 有个元素,可以将个元素分成多组,每组的元素编号必须是连续的. 设每组的为,则每组的价值公式为. 求最大价值和. Input 输入由三行组成. 第一行包含一个整数,表示士兵的总数 ...

  6. 【BZOJ-2436】嘉年华 DP + 优化

    2436: [Noi2011]Noi嘉年华 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 529  Solved: 382[Submit][Statu ...

  7. 【poj2942】 Knights of the Round Table

    http://poj.org/problem?id=2942 (题目链接) 题意 有n个骑士要去参加圆桌会议,他们将围成一圈,想要他们不打架,当且仅当参加圆桌会议的骑士数为奇数并且相邻的两个骑士不互相 ...

  8. Uva1624 Knots

    极其鬼畜的题. 初见根本没有思路. 二见根本没有思路. …… 多年(并不)之后突然想到,也许可以用链表模拟. 先用链表把每一个节点串起来,并对有覆盖的地方进行标记. 模拟解锁操作,如果一个节点和它所覆 ...

  9. MyBB \inc\class_core.php <= 1.8.2 unset_globals() Function Bypass and Remote Code Execution(Reverse Shell Exploit) Vulnerability

    catalogue . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 MyBB's unset_globals() function ca ...

  10. list去除并且把值相加

    package list; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import ja ...