spring的事务提交与回滚机制

事务超时:
@Transactional(timeout = 60)
如果用这个注解描述一个方法的话,线程已经跑到方法里面,如果已经过去60秒了还没跑完这个方法并且线程在这个方法中的后面还有涉及到对数据库的增删改查操作时会报事务超时错误(会回滚)。如果已经过去60秒了还没跑完但是后面已经没有涉及到对数据库的增删改查操作,那么这时不会报事务超时错误(不会回滚)。

回滚:
      答案是 RuntimeException或者Error,即unchecked Exception 详见http://blog.csdn.net/u012557814/article/details/50685374

注意:如果事务在
try{
 }catch(Exception e){
  e.printStackTrace();
}
中跑,并且catch中只是打印e的话,那么事务不会rollback。因为异常被catch掉了,框架不知道发生了异常。

如果想要rollback,可以加上rollbackFor=Exception.class,然后:
在方法上添加 throws  Exception,将方法中出现的异常抛出给spring事务,
②去掉方法体中的try catch
③catch (Exception e) {  throw e;}继续向上抛,目的是让spring事务捕获这个异常。
④不加rollbackFor=Exception.class,catch(){
    throw new RunTimeException();
}
如果不加rollbackFor=Exception.class,抛出new Exception() 是不会回滚的。Spring源码如下:
public boolean rollbackOn(Throwable ex) { 
     return (ex instanceof RuntimeException || ex instanceof Error);
如果是RuntimeException或Error的话,就返回True,表示要回滚,否则返回False,表示不回滚。

只有spring事务捕获到Exception异常后,@Transactional(rollbackFor=Exception.class),
才会起到应有的作用
catch (Exception e) {
              e.printStackTrace();        
}
这句是捕获try中出现的Exception然后将异常信息打印出来,仅仅是打印出来,然后什么也没干。

@Transactional(timeout = 60,rollbackFor=Exception.class)与@Transactional(timeout = 60)区别
rollbackFor=Exception.class的作用是让checked例外也回滚,即让编译错误也回滚。
需要注明的是:
1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)
2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
checked exception是编译时的错误,Unchecked exception是运行时错误,详见
http://meng702.iteye.com/blog/998379

转载:http://blog.csdn.net/heweimingming/article/details/51841133

附:

今天做一个插入操作时发现事务不起作用,尝试了各种办法都没有奏效,结果发现是mysql数据库使用的引擎类型是MYISAM,这种引擎是不支持事务的,于是更换为innodb。

另外想说的是,在springmvc的service层处理事务时,可以在service使用try..catch..,catch中主动抛出.运行时异常,方法上写@Transactional即可,异常抛给controller处理。另外一种办法,service不catch,也不用throws,直接就是@Transactional。








没有更多推荐了,返回首页