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

接下来测试事务传播的REQUIRES_NEW。

Service层

Service层代码在这里不展示了,主要将EMPService1Impl类中的方法事务传播属性设置为REQUIRED,EMPService2Impl类中的方法事务传播属性为REQUIRES_NEW,下面代码进行了注释说明。

LayerT层代码

 1 package LayerT;
 2 
 3 import javax.annotation.Resource;
 4 
 5 import org.springframework.stereotype.Component;
 6 import org.springframework.transaction.annotation.Propagation;
 7 import org.springframework.transaction.annotation.Transactional;
 8 
 9 import Entity.EMP;
10 import Service.EMPService1;
11 import Service.EMPService2;
12 /**
13  * 测试Requires_New
14  * @author yangchaolin
15  *
16  */
17 @Component("requiredNewTest")
18 public class RequiredNewTest {
19     @Resource(name="service1")
20     EMPService1 service1;
21     @Resource(name="service2")
22     EMPService2 service2;
23     /**
24      * 外层方法没有事务,但是抛出异常,内层方法一个事务为Required,一个为Requires_New,以下注释了
25      * @param emp1
26      * @param emp2
27      */
28     public void testRequiredNewWithoutTransaction1(EMP emp1,EMP emp2) {
29         service1.addEmp1(emp1);//事务传播为Required
30         service2.addEmp2(emp2);//事务传播为Requires_New
31         throw new RuntimeException();
32     }
33     /**
34      * 外层方法没有事务,但是内层方法抛出异常
35      * @param emp1
36      * @param emp2
37      */
38     public void testRequiredNewWithoutTransaction2(EMP emp1,EMP emp2) {
39         service1.addEmp1(emp1);//事务传播为Required
40         service2.addEmp2WithException(emp2);//事务传播为Requires_New
41     }
42     /**
43      * 外层方法有事务,并且抛出异常
44      * @param emp1
45      * @param emp2
46      */
47     @Transactional(propagation=Propagation.REQUIRED)
48     public void testRequiredNewWithTransaction1(EMP emp1,EMP emp2) {
49         service1.addEmp1(emp1);//事务传播为Required
50         service2.addEmp2(emp2);//事务传播为Requires_New
51         throw new RuntimeException();
52     }
53     /**
54      * 外层方法有事务,由内层方法抛出异常
55      * @param emp1
56      * @param emp2
57      * @param emp3
58      */
59     @Transactional(propagation=Propagation.REQUIRED)
60     public void testRequiredNewWithTransaction2(EMP emp1,EMP emp2,EMP emp3) {
61         service1.addEmp1(emp1);//事务传播为Required
62         service2.addEmp2(emp2);//事务传播为Requires_New
63         service2.addEmp2WithException(emp3);//事务传播为Requires_New
64     }
65     /**
66      * 外层方法有事务,内层方法抛出的异常被捕获
67      * @param emp1
68      * @param emp2
69      * @param emp3
70      */
71     @Transactional(propagation=Propagation.REQUIRED)
72     public void testRequiredNewWithTransaction3(EMP emp1,EMP emp2,EMP emp3) {
73         service1.addEmp1(emp1);//事务传播为Required
74         service2.addEmp2(emp2);//事务传播为Requires_New
75         try {
76         service2.addEmp2WithException(emp3);//事务传播为Requires_New
77         }catch(Exception e) {
78             System.out.println("回滚");
79         }
80     }
81 }

测试代码

 1 package TestCase;
 2 
 3 import org.junit.Test;
 4 
 5 import Entity.EMP;
 6 import LayerT.RequiredNewTest;
 7 
 8 public class requireNewTestCase extends baseTest{
 9     @Test
10     public void test1() {
11         RequiredNewTest T1=ac.getBean("requiredNewTest",RequiredNewTest.class);
12         EMP emp1=new EMP("张三",18);
13         EMP emp2=new EMP("李四",28);
14         T1.testRequiredNewWithoutTransaction1(emp1, emp2);
15       }    
16     @Test
17     public void test2() {
18         RequiredNewTest T1=ac.getBean("requiredNewTest",RequiredNewTest.class);
19         EMP emp1=new EMP("张三",18);
20         EMP emp2=new EMP("李四",28);
21         T1.testRequiredNewWithoutTransaction2(emp1, emp2);
22       }    
23     @Test
24     public void test3() {
25         RequiredNewTest T1=ac.getBean("requiredNewTest",RequiredNewTest.class);
26         EMP emp1=new EMP("张三",18);
27         EMP emp2=new EMP("李四",28);
28         T1.testRequiredNewWithTransaction1(emp1, emp2);
29       }    
30     @Test
31     public void test4() {
32         RequiredNewTest T1=ac.getBean("requiredNewTest",RequiredNewTest.class);
33         EMP emp1=new EMP("张三",18);
34         EMP emp2=new EMP("李四",28);
35         EMP emp3=new EMP("王五",22);
36         T1.testRequiredNewWithTransaction2(emp1, emp2, emp3);
37       }    
38     @Test
39     public void test5() {
40         RequiredNewTest T1=ac.getBean("requiredNewTest",RequiredNewTest.class);
41         EMP emp1=new EMP("张三",18);
42         EMP emp2=new EMP("李四",28);
43         EMP emp3=new EMP("王五",22);
44         T1.testRequiredNewWithTransaction3(emp1, emp2, emp3);
45       }    
46 }

测试结果

(1)外层方法没有事务

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

 

 

 

结论:外层方法如果没有事务,内层方法事务相互独立,在事务传播为REQUIRED_NEW的情况下,内层方法如果抛出异常将不会插入数据,数据回滚,但不会影响其他内层方法。

(2)外层方法有事务

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

 

 

 

 

 

结论:如果外层事务传播属性为默认的REQUIRED,内层方法如果有同样的事务传播属性,将绑定在一起,只要外层方法抛出异常,或者感知内层方法抛出的异常,都会回滚。而内层方法事务传播属性为REQUIRES_NEW时,会单独开辟一个自己的事务,不受外层事务的干扰。

 

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

上一篇:PyTorch 1.0 中文文档:自动求导机制


下一篇:redis requires ruby version 2.2.2的解决方案