在准备好前期的项目搭建后,接下来就一个个的测试,首先测试事务传播的Required

Service层两个实现类

Service层两个实现类,只是更换了方法事务传播的属性,其他都一样,后续测试也只修改传播的属性即可,这里只列一次便于理解。

 package Service;

 import javax.annotation.Resource;

 import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import DAO.EmpDAO;
import Entity.EMP; @Service("service1")
public class EMPService1Impl implements EMPService1{ @Resource(name="empDAO")
EmpDAO dao; @Transactional(propagation=Propagation.REQUIRED)
public void addEmp1(EMP emp) {
dao.addEMP1(emp);
} }
 package Service;

 import javax.annotation.Resource;

 import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import DAO.EmpDAO;
import Entity.EMP; @Service("service2")
public class EMPService2Impl implements EMPService2{ @Resource(name="empDAO")
EmpDAO dao; @Transactional(propagation=Propagation.REQUIRED)
public void addEmp2(EMP emp) {
dao.addEMP2(emp);
} @Transactional(propagation=Propagation.REQUIRED)
public void addEmp2WithException(EMP emp) {
dao.addEMP2(emp);
throw new RuntimeException();
} }

LayerT层代码

 package LayerT;

 import javax.annotation.Resource;

 import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import Entity.EMP;
import Service.EMPService1;
import Service.EMPService2; /**
* 测试Required
* @author yangchaolin
*
*/
@Component("requiredTest")
public class RequiredTest {
@Resource(name="service1")
EMPService1 service1;
@Resource(name="service2")
EMPService2 service2; /**
* 外层方法没有事务,但是抛出异常
* @param emp1
* @param emp2
*/
public void testRequiredWithoutTransaction1(EMP emp1,EMP emp2) {
service1.addEmp1(emp1);
service2.addEmp2(emp2);
throw new RuntimeException();
}
/**
* 外层方法没有事务,内层有方法抛出异常
* @param emp1
* @param emp2
*/
public void testRequiredWithoutTransaction2(EMP emp1,EMP emp2) {
service1.addEmp1(emp1);
service2.addEmp2WithException(emp2);
}
/**
* 外层方法有事务,但是抛出异常
* @param emp1
* @param emp2
*/
@Transactional(propagation=Propagation.REQUIRED)
public void testRequiredWithTransaction1(EMP emp1,EMP emp2) {
service1.addEmp1(emp1);
service2.addEmp2(emp2);
throw new RuntimeException();
}
/**
* 外层方法有事务,内层有方法抛出异常
* @param emp1
* @param emp2
*/
@Transactional(propagation=Propagation.REQUIRED)
public void testRequiredWithTransaction2(EMP emp1,EMP emp2) {
service1.addEmp1(emp1);
service2.addEmp2WithException(emp2);
}
/**
* 外层方法有事务,内存方法抛出的异常被捕获
* @param emp1
* @param emp2
*/
@Transactional(propagation=Propagation.REQUIRED)
public void testRequiredWithTransaction3(EMP emp1,EMP emp2) {
service1.addEmp1(emp1);
try {
service2.addEmp2WithException(emp2);
}catch(Exception e) {
System.out.println("回滚");
}
} }

测试代码

其中baseTest为父类,里面读取Spring-MVC.xml和Spring-Mybatis配置文件后初始化了ApplicationContext,继承它后后续其他事务传播属性的测试就不需要重复写这一部分代码。

 package TestCase;

 import org.junit.Test;

 import Entity.EMP;
import LayerT.RequiredTest; public class requiredTestCase extends baseTest{
@Test
public void test1() {
RequiredTest T1=ac.getBean("requiredTest",RequiredTest.class);
EMP emp1=new EMP("张三",18);
EMP emp2=new EMP("李四",28);
T1.testRequiredWithoutTransaction1(emp1, emp2);
}
@Test
public void test2() {
RequiredTest T1=ac.getBean("requiredTest",RequiredTest.class);
EMP emp1=new EMP("张三",18);
EMP emp2=new EMP("李四",28);
T1.testRequiredWithoutTransaction2(emp1, emp2);
}
@Test
public void test3() {
RequiredTest T1=ac.getBean("requiredTest",RequiredTest.class);
EMP emp1=new EMP("张三",18);
EMP emp2=new EMP("李四",28);
T1.testRequiredWithTransaction1(emp1, emp2);
}
@Test
public void test4() {
RequiredTest T1=ac.getBean("requiredTest",RequiredTest.class);
EMP emp1=new EMP("张三",18);
EMP emp2=new EMP("李四",28);
T1.testRequiredWithTransaction2(emp1, emp2);
}
@Test
public void test5() {
RequiredTest T1=ac.getBean("requiredTest",RequiredTest.class);
EMP emp1=new EMP("张三",18);
EMP emp2=new EMP("李四",28);
T1.testRequiredWithTransaction3(emp1, emp2);
}
}

(1)外层方法没有事务测试结果

test1 张三插入,李四插入
test2 张三插入,李四未插入

结论:在外层方法没有开启事务的情况下,传播属性为Required的方法,会各自执行事务,互不干扰,当方法出现异常时,会出现回滚,如李四就未插入。

(2)外层方法有事务测试结果

test3 张三未插入,李四未插入
test4 张三未插入,李四未插入
test5 张三未插入,李四未插入

结论:在外层方法开启事务,并且传播属性为默认Required的时候,内层方法与外层方法事务传播属性一样,会将事务绑定在一起,不论是外层还是内层方法出现异常,都会导致数据回滚,即使将内层抛出异常的方法捕获也没有用。

参考博客:https://segmentfault.com/a/1190000013341344

云笔记项目-Spring事务学习-传播Requried的更多相关文章

  1. 云笔记项目-Spring事务学习-传播NOT_SUPPORTED

    接下来测试事务传播属性设置为NOT_SUPPORTED Service层 Service层主要设置如下,其中还插入了REQUIRED作为比较. package Service; import java ...

  2. 云笔记项目-Spring事务学习-传播SUPPORTS

    接下来测试事务传播属性SUPPORTS Service层 Service层将方法的事务传播属性设置为SUPPORTS LayerT层代码 package LayerT; import javax.an ...

  3. 云笔记项目-Spring事务学习-传播NEVER

    接下来测试事务传播属性NEVER Service层 Service层中设置事务传播属性都为NEVER. LayerT层代码 package LayerT; import javax.annotatio ...

  4. 云笔记项目-Spring事务学习-传播MANDATORY

    接下来测试事务传播属性MANDATORY Service层 所有Service层实现类都设置事务传播属性为MANDATORY. LayerT层代码 package LayerT; import jav ...

  5. 云笔记项目-Spring事务学习-传播NESTED

    接下来测试事务传播属性NESTED Service层 Service层方法事务传播属性都设置为NESTED. LayerT层代码 package LayerT; import javax.annota ...

  6. 云笔记项目-Spring事务学习-传播REQUIRES_NEW

    接下来测试事务传播的REQUIRES_NEW. Service层 Service层代码在这里不展示了,主要将EMPService1Impl类中的方法事务传播属性设置为REQUIRED,EMPServi ...

  7. 云笔记项目-Spring事务学习_测试准备

    在做云笔记项目的过程中,顺便简单的学习了Spring的事务概念,业务以如果添加笔记,则增加用户星星数目作为例子,引入了事务的概念.类似注册送积分之类的,云笔记项目以增加笔记就送星星来说明事务.具体在添 ...

  8. Spring事务的传播行为 @Transactional(转)

    Spring事务的传播行为 在service类前加上@Transactional,声明这个service所有方法需要事务管理.每一个业务方法开始时都会打开一个事务. Spring默认情况下会对运行期例 ...

  9. Spring事务的传播行为 @Transactional

    Spring事务的传播行为http://blog.csdn.net/cuker919/article/details/5957209 在service类前加上@Transactional,声明这个se ...

随机推荐

  1. PHP swoole实现redis订阅和发布

    前戏:实现用户下单,服务器通知后台接收订单...类似美团外卖 1.首先要实现一个订阅程序 $result = $client->connect('127.0.0.1', 6379, functi ...

  2. ZoomIt: 非PPT演示必备辅助软件

    下载地址:https://docs.microsoft.com/zh-cn/sysinternals/downloads/zoomit 使用方法: 另一个免费的屏幕标注工具:Pointofix v1. ...

  3. Optaplanner规划引擎的工作原理及简单示例(2)

    开篇 在前面一篇关于规划引擎Optapalnner的文章里(Optaplanner规划引擎的工作原理及简单示例(1)),老农介绍了应用Optaplanner过程中需要掌握的一些基本概念,这些概念有且于 ...

  4. CDNI - RFC7336翻译

    CDNI框架 摘要 本文档提出了CDNI的一个框架.框架的目的是提供对CDNI问题空间的总体描述,和描述CDN互连所需的各种组件之间的 关系.CDNI需要指定接口和机制解决诸如请求路由,分发交换元数据 ...

  5. JAVA之Mybatis基础入门--框架搭建与简单查询

    JAVA中,操作数据库有JDBC.hibernate.Mybatis等技术,今天整理了下,来讲一讲下Mybatis.也为自己整理下文档: hibernate是一个完全的ORM框架,是完全面向对象的.但 ...

  6. 记录Redis使用中遇到的两个问题(原子性及数据完整性)

    1.使用Redis作为分布式锁的原子性问题 原方案: ① SETNX $LOCK_BUSI_KEY $REQ_ID ② EXPIRE $LOCK_BUSI_KEY $LOCK_TIME 问题: 使用S ...

  7. 高性能 TCP & HTTP 通信框架 HP-Socket v4.3.1

    HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...

  8. ubuntu远程windows桌面

    最近把系统装成了ubuntu,需要远程windows  ,就用到了ubuntu的 rdesktop工具 1.先打开终端输入 rdesktop  看系统是否安装了  rdesktop  如果没有安装需要 ...

  9. 详细解说Windows 8.1与Windows 8的区别(Win8.1与Win8区别)

    详细解说Windows 8.1与Windows 8的区别(Win8.1与Win8区别) 本文转自“吾乐吧软件站”,原文链接:http://www.wuleba.com/?p=23082 最近,吾乐吧软 ...

  10. python———day04

    一.tuple (元组) 元组被称为制度列表,可以被查询,但是不能被修改. 元组写在小括号里(),元素之间用逗号隔开. tup1 = () #空元组 tup2 = (20,) #只有一个元素的元组 记 ...