1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。‘

3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

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

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

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

罗列了7种spring的事务传播行为,我们具体来看看它的实现。在这里,我们使用spring annotation注解实现事务。

实现事务的类BusinessServiceImpl

  1. package com.aop;
  2.  
  3. import org.springframework.aop.support.AopUtils;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Service;
  6. import org.springframework.transaction.annotation.Isolation;
  7. import org.springframework.transaction.annotation.Propagation;
  8. import org.springframework.transaction.annotation.Transactional;
  9.  
  10. import com.entity.Student;
  11.  
  12. @Service("businessSerivce")
  13. public class BusinessServiceImpl implements IBaseService {
  14.  
  15. @Autowired
  16. IStudentDao studentDao;
  17.  
  18. @Autowired
  19. IBaseServiceB baseServiceb;
  20.  
  21. @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
  22. public String doA() throws Exception {
  23. Student st = new Student();
  24. st.setId(1);
  25. st.setSex("girl");
  26. st.setUsername("zx");
  27. studentDao.insertStudent(st);
  28.  
  29. System.out.println(baseServiceb);
  30. System.out.println("是否是代理调用,AopUtils.isAopProxy(baseServiceb) : " + AopUtils.isAopProxy(baseServiceb));
  31. System.out
  32. .println("是否是cglib类代理调用,AopUtils.isCglibProxy(baseServiceb) : " + AopUtils.isCglibProxy(baseServiceb));
  33. System.out.println("是否是jdk动态接口代理调用,AopUtils.isJdkDynamicProxy(baseServiceb) : "
  34. + AopUtils.isJdkDynamicProxy(baseServiceb));
  35.  
  36. //使用代理调用方法doB()
  37. baseServiceb.doB();
  38. int i = 1 / 0;// 抛出异常,doB()的事务事务回滚
  39. return "success";
  40. }
  41.  
  42. // @Transactional(propagation = Propagation.REQUIRES_NEW, isolation =
  43. // Isolation.DEFAULT, rollbackFor = Exception.class)
  44. // public String doB() throws Exception {
  45. // Student st = new Student();
  46. // st.setId(2);
  47. // st.setSex("girl");
  48. // st.setUsername("zx2");
  49. // studentDao.insertStudent(st);
  50. //
  51. // return "success";
  52. // }
  53.  
  54. }

实现事务的类BusinessServiceImpl

  1. package com.aop;
  2.  
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Service;
  5. import org.springframework.transaction.annotation.Isolation;
  6. import org.springframework.transaction.annotation.Propagation;
  7. import org.springframework.transaction.annotation.Transactional;
  8.  
  9. import com.entity.Student;
  10.  
  11. @Service("businessSerivceB")
  12. public class BusinessServiceImplB implements IBaseServiceB {
  13.  
  14. @Autowired
  15. IStudentDao studentDao;
  16.  
  17. @Transactional(propagation = Propagation.REQUIRES_NEW,isolation=Isolation.DEFAULT,rollbackFor=Exception.class)
  18. public String doB() throws Exception {
  19. Student st = new Student();
  20. st.setId(2);
  21. st.setSex("girl");
  22. st.setUsername("zx2");
  23. studentDao.insertStudent(st);
  24. return "success";
  25. }
  26.  
  27. }

测试类:

  1. package com.aop;
  2.  
  3. import org.springframework.beans.factory.BeanFactory;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5.  
  6. import com.thread.service.IBaseFacadeService;
  7.  
  8. //@RunWith(SpringJUnit4ClassRunner.class)
  9. //@ContextConfiguration(locations = { "classpath:/spring-ibatis.xml", "classpath:/spring-jdbctemplate.xml" })
  10. public class TestStudentDao {
  11.  
  12. public static void main(String[] args) {
  13. try {
  14. BeanFactory factory = new ClassPathXmlApplicationContext("spring-jdbctemplate.xml");
  15. IBaseService service = (IBaseService) factory.getBean("businessSerivce");
  16.  
  17. service.doA();
  18. } catch (Exception e) {
  19. // TODO Auto-generated catch block
  20. e.printStackTrace();
  21. }
  22. }
  23. }

测试结果:

om.aop.BusinessServiceImplB@14b75fd9
是否是代理调用,AopUtils.isAopProxy(baseServiceb) : true
是否是cglib类代理调用,AopUtils.isCglibProxy(baseServiceb) : true
是否是jdk动态接口代理调用,AopUtils.isJdkDynamicProxy(baseServiceb) : false
java.lang.ArithmeticException: / by zero

从测试结果可以看到,我们在数据库中成功插入了doB()方法中要插入的数据,而doA()中插入的数据被回滚了,这是因为我们在doB()方法中加入ROPAGATION_REQUIRES_NEW传播行为,doB()创建了属于自己的事务,挂起了doA()中的事务,所以事务B提交了,而事务A因为执行异常插入的数据被回滚了。

如果我们将BusinessServiceImplB做下修改,改为第一种传播行为ROPAGATION_REQUIRED

  1. package com.aop;
  2.  
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Service;
  5. import org.springframework.transaction.annotation.Isolation;
  6. import org.springframework.transaction.annotation.Propagation;
  7. import org.springframework.transaction.annotation.Transactional;
  8.  
  9. import com.entity.Student;
  10.  
  11. @Service("businessSerivceB")
  12. public class BusinessServiceImplB implements IBaseServiceB {
  13.  
  14. @Autowired
  15. IStudentDao studentDao;
  16.  
  17. @Transactional(propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT,rollbackFor=Exception.class)
  18. public String doB() throws Exception {
  19. Student st = new Student();
  20. st.setId(2);
  21. st.setSex("girl");
  22. st.setUsername("zx2");
  23. studentDao.insertStudent(st);
  24. return "success";
  25. }
  26.  
  27. }

测试结果:

com.aop.BusinessServiceImplB@97c87a4
是否是代理调用,AopUtils.isAopProxy(baseServiceb) : true
是否是cglib类代理调用,AopUtils.isCglibProxy(baseServiceb) : true
是否是jdk动态接口代理调用,AopUtils.isJdkDynamicProxy(baseServiceb) : false
java.lang.ArithmeticException: / by zero

从结果可以看到,我们没有成功插入数据,这是为什么呢?因为我们使用的是第一种传播行为PROPAGATION_REQUIRED ,doB()方法被加入到doA()的事务中,doA()执行时抛出了异常,因为doB()和doA()同属于一个事务,则执行操作被一起回滚了。其实在doB()中我们不加入注解,也等同PROPAGATION_REQUIRED的效果。

接下来我们再来看看第五种传播行为PROPAGATION_NOT_SUPPORTED,我们同样修改B类,如下

  1. package com.aop;
  2.  
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Service;
  5. import org.springframework.transaction.annotation.Isolation;
  6. import org.springframework.transaction.annotation.Propagation;
  7. import org.springframework.transaction.annotation.Transactional;
  8.  
  9. import com.entity.Student;
  10.  
  11. @Service("businessSerivceB")
  12. public class BusinessServiceImplB implements IBaseServiceB {
  13.  
  14. @Autowired
  15. IStudentDao studentDao;
  16.  
  17. @Transactional(propagation = Propagation.NOT_SUPPORTED,isolation=Isolation.DEFAULT,rollbackFor=Exception.class)
  18. public String doB() throws Exception {
  19. Student st = new Student();
  20. st.setId(2);
  21. st.setSex("girl");
  22. st.setUsername("zx2");
  23. studentDao.insertStudent(st);
  24. return "success";
  25. }
  26.  
  27. }

测试结果:


可以看到doB()方法成功插入了数据。doA()方法中插入的数据被回滚了。这是因为传播行为PROPAGATION_NOT_SUPPORTED是doB()以非事务执行的,并且提交了。所以当doA()的事务被回滚时,doB()的操作没有被回滚。

其他的传播行为就不一一列举了,机制是差不多的。

注意:在上面的实例中,我没有把doB()方法放在类BusinessServiceImpl,而是放在BusinessServiceImplB中,这是因为spring通过扫描所有含有注解的@Trasation的方法,使用aop形成事务增强advise。但是加入增强时是通过代理对象调用方法的形式加入的,如果将doB()方法放在doA()方法直接调用时,在调用doB()方法的时候是通过当前对象来调用doB()方法的,而不是通过代理来调用的doB()方法,这个时候doB()方法上加的事务注解就失效了不起作用。在Spring事务传播行为在内部方法不起作用讲到。

spring配置文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  4. xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xmlns:aop="http://www.springframework.org/schema/aop"
  7. xsi:schemaLocation="
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  11. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  12. http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd"
  13. default-lazy-init="false">
  14.  
  15. <context:component-scan base-package="com.aop"/>
  16. <aop:aspectj-autoproxy proxy-target-class="true"/>
  17. <!-- 数据 -->
  18. <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
  19. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  20. <property name="url" value="jdbc:mysql://localhost:3306/lpWeb"/>
  21. <property name="username" value="root"/>
  22. <property name="password" value="root123"/>
  23. </bean>
  24.  
  25. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  26. <property name = "dataSource" ref="dataSource"/>
  27. </bean>
  28.  
  29. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  30. <property name="dataSource" ref="dataSource"/>
  31. </bean>
  32.  
  33. <tx:annotation-driven transaction-manager="transactionManager" />
  34. </beans>

Spring 7种事务传播行为的更多相关文章

  1. Spring 7种事务传播类型

    转载:https://www.cnblogs.com/originate918/p/6226342.html PROPAGATION_REQUIRED及其他6种事务传播行为种类. Spring在Tra ...

  2. 手把手带你实战下Spring的七种事务传播行为

    目录 本文目录 一.什么是事务传播行为? 二.事务的7种传播行为 三.7种传播行为实战 本文介绍Spring的七种事务传播行为并通过代码演示下. 本文目录 一.什么是事务传播行为? 事务传播行为(pr ...

  3. spring事务:事务控制方式,使用AOP控制事务,七种事务传播行为,声明事务,模板对象,模板对象原理分析

    知识点梳理 课堂讲义 1)事务回顾 1.1)什么是事务-视频01 事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败. 1.2)事务的作用 事务特征(ACID) 原子 ...

  4. Spring7种事务传播行为类型--PROPAGATION_REQUIRED及其他6种事务传播行为种类

    PROPAGATION_REQUIRED及其他6种事务传播行为种类,有需要的朋友可以参考下. Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务 ...

  5. 面试官:说说Spring中的事务传播行为

    前言 在开发中,相信大家都使用过Spring的事务管理功能.那么,你是否有了解过,Spring的事务传播行为呢? Spring中,有7种类型的事务传播行为.事务传播行为是Spring框架提供的一种事务 ...

  6. -手写Spring注解版本&事务传播行为

    视频参考C:\Users\Administrator\Desktop\蚂蚁3期\[www.zxit8.com] 0018-(每特教育&每特学院&蚂蚁课堂)-3期-源码分析-手写Spri ...

  7. spring中的事务传播机制

    1.事务的实现思想 在spring中要想某个方法具有事务,只要在方法前加一个@Transactional注解.然后spring就会利用aop思想,在这个方法执行前开启事务, 在方法执行后选择提交事务或 ...

  8. spring常用的事务传播属性说明

    事务Transaction,就是一组操作数据库的动作集合.事务是现代数据库理论中的核心概念之一.如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事务.当所有的步骤像一个操作一样被 ...

  9. Spring的七种事务传播机制

    概述 当我们调用一个基于Spring的Service接口方法(如UserService#addUser())时,它将运行于Spring管理的事务环境中,Service接口方法可能会在内部调用其它的Se ...

随机推荐

  1. MySQL/InnoDB中,对于锁的认识

    MySQL/InnoDB的加锁,一直是一个面试中常问的话题.例如,数据库如果有高并发请求,如何保证数据完整性?产生死锁问题如何排查并解决?我在工作过程中,也会经常用到,乐观锁,排它锁,等.于是今天就对 ...

  2. html-prepend

    $('.classDiv').prepend('<span>添加</span>')

  3. oracle insert 返回ID

    create or replace procedure getid(v_id out number)as  v_sql varchar2(500); begin v_sql:='insert into ...

  4. iPhone投影

    iPhone投影到Mac上面的操作,用QuickTime,选择主菜单的新建屏幕录制,然后点击录制按钮右边的箭头,相机切换到iPhone就可以了. 相关操作参照 https://jingyan.baid ...

  5. iOS工程结构理解

    iOS开发中关于工程结构有三个关键部分,分别是:Targets,projects 和 workspaces. Targets指定了工程或者库文件如何编译,包括building setting,comp ...

  6. Python基础3 函数、递归、内置函数

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测 ...

  7. Dubbo的学习

    Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. Dubbo是一款高性能.轻量级的开源Java RP ...

  8. NRF51822之使用外部32Mhz晶振

    硬件平台为微雪BLE400的(将原来的16mhz晶振改为32mhz.两个旁电容改为22pf) 以nRF51_SDK_10.0.0_dc26b5e\examples\ble_peripheral\ble ...

  9. 回溯法 leetcode题解 Combination Sum 递归法

    题目大意:给出一个数组,用这些数组里的元素去凑一个target.元素可以重复取用. 感觉对这种题目还是生疏的.脑子里有想法,但是不知道怎么表达出来. 先记录下自己的递归法.应该还可以用循环实现. 回溯 ...

  10. Linux下Mongodb安装和启动配置 原

    1.安装 略 2.配置 01.mkdir /usr/local/mongodb/data 0.touch /usr/local/mongodb/logs 03.cd /usr/local/mongod ...