spring事务陷阱

今天在调查bug时发现spring事务使用的问题,整理如下:

在service类前加上@Transactional时,容易忽略的2个问题:

  1. 事务嵌套开启的问题

    在同一个类中,如果有methodA、methodB、methodC,spring默认的代理策略中相同类中方法调用是直接调用的,这样造成的结果是:间接调用的方法上添加的事务注解不会生效,示例伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
classA:
public  boolean  methodA()  throws  Exception {
     this .methodB();
     this .methodC();
     return  true ;
}
     
     
@Transactional (readOnly= false )
public  boolean  methodB()  throws  Exception {
     return  this .synchronize( null );
}
     
@Transactional (readOnly= false )
public  boolean  methodC()  throws  Exception {
     return  this .synchronize( null );
}
 
------------
 
classB:
classA.methodA();

   上述classB中调用classA的methodA方法,不会开启spring事务!如果想要开启事务,有2个办法:

1)在methodA上添加@Transactional注解

2)在methodA中的这样调用methodB、methodC:

 

1
2
3
4
5
public  boolean  methodA()  throws  Exception {
     classA.methodB();
     classA.methodC();
     return  true ;
}

 

扫描二维码关注公众号,回复: 543910 查看本文章

2. 事务回滚未生效

这个大部分是粗心大意造成的,参考以下伪代码:

1
2
3
4
5
6
7
8
9
@Transactional (readOnly= false )
public  boolean  methodC()  throws  Exception {
         try  {
             return  this .synchronize( null );
         } catch (Exception ex) {
             //nothoing
         }
 
}

以上代码将所有异常捕获,但是没有抛出,spring代理类会认为没有异常抛出,因此不会回滚事务

 

 

【】

spring的@Transaction是通过aop实现的,类似于对这个类生成了一个包装类,从外部调用时,会经过这个包装层,内部调用不会经过。

没错,spring的事务是通过代理实现的,

猜你喜欢

转载自lehsyh.iteye.com/blog/2059005
今日推荐