通过这篇文章,你将学习到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. Cell右滑的动作状态

    //允许cell可以进行编辑 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)index ...

  2. 【BZOJ-2095】Bridge 最大流 + 混合图欧拉回路 + 二分

    2095: [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 604  Solved: 218[Submit][Stat ...

  3. poj1113 凸包

    result=对所有点凸包周长+pi*2*L WA了一次,被Pi的精度坑了 以后注意Pi尽可能搞精确一点.Pi=3.14还是不够用 Code: #include<vector> #incl ...

  4. qibocms /hr/listperson.php File Arbitrarily Include Vul Via Variable Uninitialization && Front Page Upload WEBSHELL

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Relevant Link:2. 漏洞触发条件 . 找到前台文件上传点 ...

  5. Linux VFS Extended Attribute And Access Control Table

    catalog . 简介 . 扩展属性 . 访问控制表 . 小结 0. 简介 许多文件系统都提供了一些特性,扩展了VFS层提供的标准功能,虚拟文件系统不可能为所有特性都提供具体的数据结构.超出标准的U ...

  6. Visual Studio原生开发的20条调试技巧(下)

    我的上篇文章<Vistual Studio原生开发的10个调试技巧>引发了很多人的兴趣,所以我决定跟大家分享更多的调试技巧.接下来你又能看到一些对于原生应用程序的很有帮助的调试技巧(接着上 ...

  7. DNS介绍

    DNS出现及演化 网络出现的早期 是使用IP地址通讯的,那时就几台主机通讯.但是随着接入网络主机的增多,这种数字标识的地址非常不便于记忆,UNIX上就出现了建立一个叫做hosts的文件(Linux和w ...

  8. zabbix 3.0快速安装简介(centos 6)

    zabbix快速安装 系统版本:centos 6 1.yum源配置和zabbix.msyql安装 rpm -ivh http://mirrors.aliyun.com/zabbix/zabbix/3. ...

  9. easyUI中tree的简单使用

    一.在JS中的代码 $('#tt').tree({ url: baseCtx + 'lib/easyui-1.4/demo/tree/tree_data1.json',//tree数据的来源,json ...

  10. GLSL Interface Block参考

    http://www.opengl.org/wiki/Interface_Block_(GLSL) http://stackoverflow.com/questions/9916103/opengl- ...