在使用SPRING的事务控制时,事务一般都是加在SERVICE层的,这个时候如果一个SERVICE调用另一个

SERVICE时有可能会出现事务控制问题,比如第二个SERVICE抛出了异常,第一个SERVICE却正常提交了,

比如下面这个例子:

事务配置

  1. <tx:method name="add*" propagation="REQUIRED"/>  


测试代码

  1. @Test  

  2. public void testAddUser() throws Exception {  

  3.     UserServiceImpl service = (UserServiceImpl) context.getBean("userServiceImpl", UserServiceImpl.class);  

  4.     USER u = new USER();  

  5.     u.setCreated("2015-05-05");  

  6.     u.setCreator(123);  

  7.     u.setName("test");  

  8.     u.setPassword("test");  

  9.     service.addUser(u);  

  10. }  


SERVICE层:

  1. public void addUser(USER user) throws Exception {  

  2.     userDaoImpl.saveUser(user);  

  3.     delByUsername(user.getName());  

  4. }  

  5.   

  6. public void delByUsername(String name) throws Exception {  

  7.     throw new FileNotFoundException("fjkdl");  

  8. }  

    当第二个SERVICE抛出异常的时候,第一个SERVICE却正常提交了,USER被加入到了数据库当中。

    先不改配置,我们改下SERVICE代码:

  1.     public void addUser(USER user) throws Exception {  

  2.         userDaoImpl.saveUser(user);  

  3.         delByUsername(user.getName());  

  4.     }  

  5.   

  6.     public void delByUsername(String name) throws Exception {  

  7. //        String s = null;  

  8. //        s.length();  

  9.         throw new RuntimeException("runtime e");  

  10.     }  


    让第二个SERVICE抛出运行时异常,再测试,会发现这个时候第一个SERVICE的事务也回滚了,USER

没有插入数据库中。

    从测试中我们可以发现,在事务传播为propagation="REQUIRED"的时候,如果SERVICE中抛出检查型

异常,其它的事务可以正常提交,但是如果SERVICE抛出运行时异常,则所有的SERVICE共享同一事务。

    如果我们改下配置,如下:

  1. <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>  

     这个时候,无论SERVICE里抛出运行时异常还是检查型异常,将共享同一事务,也就是说只要有异常,事务

将自动回滚。

    现在只发现了这个问题,如果大家遇到什么问题也可以提出来一起讨论下。