接下来测试事务传播的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时,会单独开辟一个自己的事务,不受外层事务的干扰。