通过这篇文章,你将学习到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. python 学习笔记6(数据库 sqlite)

    26. SQLite 轻量级的关系型数据库 SQLite是python自带的数据库,可以搭配python存储数据,开发网站等. 标准库中的 sqlite3 提供该数据库的接口. 1. 基本语法如下 c ...

  2. 【BZOJ-4520】K远点对 KD-Tree + 堆

    4520: [Cqoi2016]K远点对 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 490  Solved: 237[Submit][Status ...

  3. asp.net项目发布打包研究

    有几种思路: 1.[推荐]直接发布,然后手动打包成压缩包,需要的时候直接上传到服务器,或者在本地解压出来手动上传到虚拟空间(支持绝大多数的虚拟空间,自由度高,DZ也是采用这样的打包,FTP上传操作比较 ...

  4. hdu 3089 约瑟夫环

    原来并不知道约瑟夫环还可以递推直接解orz 约瑟夫问题的递推公式: 设f[n]表示一共n个人,数到k出局,这样最后的winner (n个人从0开始标号,即0--n-1) f[n]=(f[n-1]+k) ...

  5. Pipe

    #一边压缩一边传 一边解压 到对方的目录为/tlj/2/ / | ssh root@172.16.200.56 tar xzf - -C /tlj #在一个需要文件名的地方 使用-重定向输出到stdo ...

  6. Unity3d5.0 新UI之2048

    因为汽车系统没写出来所以,纠结之中,弄了弄新版本的UI. 做了个2048. 新版本的unity的UI必须以Canvas为基底来呈现,如果没有加画布的话可是显示不出来东西的哦. 而且作为UI上的所有组件 ...

  7. U盘容量减少的解决办法

    今天是使用以前的U盘的时候发现原来4G的U盘容量居然只剩下了700M,不是说u盘的可用空间是700M,而是在电脑上面显示的总空间为700M.在电脑上面格式化之后也没起作用. 经过Google找到了在w ...

  8. POJ 3735 Training little cats

    题意 维护一个向量, 有三种操作 将第\(i\)个数加1 将第\(i\)个数置0 交换第\(i\)个数和第\(j\)个数 Solution 矩阵乘法/快速幂 Implementation 我们将向量写 ...

  9. .net中ckeditor的应用

    ①js文件的引入 <script src="/public/ckeditor_4.4.7/ckeditor.js"></script> <script ...

  10. 本地仓库 同步到 bitbucket 远程git库

    http://blog.csdn.net/lue2009/article/details/46553829 配置ssh连接: http://blog.csdn.net/lue2009/article/ ...