【Spring.事务.异常回滚】请问Spring的声明式事务发生异常时的处理方式。

http://www.iteye.com/problems/17791

我的方法(使用伪代码表述):

Java代码
@Transactional 
public 一个业务方法(){  
  try{  
 
    //一些业务操作,期间可能会抛出运行时异常。  
     int i = 3/0;  
    ... ...  
      
    //调用A实体相关的dao方法,dao使用了Spring的DAO模版。 期间可能会出现事务冲突的问题。  
     aDao.oneMethod();  
    ... ...  
      
    //一些业务操作,期间可能会抛出运行时异常。  
     int i = 3/0;  
    if(某条件){  
      throw new 自定义的运行时异常();  
    }  
      
    ... ...  
     //调用B实体相关的dao方法,dao使用了Spring的DAO模版。 期间可能会出现事务冲突的问题。  
     bDao.oneMethod();  
     ... ...  
  }catch(Spring异常){  
 
    //做一些自定的操作。  
     ... ...  
  }  


@Transactional
public 一个业务方法(){
  try{

    //一些业务操作,期间可能会抛出运行时异常。
     int i = 3/0;
    ... ...
   
    //调用A实体相关的dao方法,dao使用了Spring的DAO模版。 期间可能会出现事务冲突的问题。
     aDao.oneMethod();
    ... ...
   
    //一些业务操作,期间可能会抛出运行时异常。
     int i = 3/0;
    if(某条件){
      throw new 自定义的运行时异常();
    }
   
    ... ...
     //调用B实体相关的dao方法,dao使用了Spring的DAO模版。 期间可能会出现事务冲突的问题。
     bDao.oneMethod();
     ... ...
  }catch(Spring异常){

    //做一些自定的操作。
     ... ...
  }
}

请问:
1. 在未调用dao方法之前,若出现了运行时异常,Spring还会做开启事务、关闭事务的动作吗?
2. 在调用aDao.oneMethod()之后、bDao.oneMethod()之前,出现运行时异常,会导致事务回滚吗?
3. 若在事务提交时出现了异常,事务在回滚后会继续抛出一个异常,虽然在我的程序中,事务抛出异常的概率较低,但是为了保险,我还是将我的业务方法的代码体用try...catch...块包了一层。请问有更好的处理方式吗?

一次问可能有点多,但是,对于比我聪明而又经验丰富的各位侠客来说就是小菜一碟了,谢谢了:)
问题补充:
补充:
对于第三点,那么,我如何捕获Spring事务抛出的异常呢?
问题补充:
谢谢各位的回复。
但是有点我不太明白,我没有看过Spring的事务的源代码,但是我认为的事务处理就是Spring环绕通知机制吧,效果应该相当于:
Java代码
try{  
     
   //开启事务  
   Transaction tx = session.beginTransactioin();  
     
  //回调我的service方法  
  myServiceMethod();  
 
  //提交事务  
  tx.commit();  
 
catch(某范围的异常){  
    
  //Spring对异常的一些自定义处理。  
  ... ...  


try{
  
   //开启事务
   Transaction tx = session.beginTransactioin();
  
  //回调我的service方法
  myServiceMethod();

  //提交事务
  tx.commit();

catch(某范围的异常){
 
  //Spring对异常的一些自定义处理。
  ... ...
}

因此——若我的理解是正确的话,在出现事务异常时,我的service方法myServiceMethod()是没法捕获事务的异常的,也就没法抛出我自定义的异常类。

表现层已经写好,由其他组维护,我不便改,而Action只捕获了公司的自定义异常及其子类异常,也就没法捕获Spring的DataAccessException。

请问还有什么好的处理方法吗?

1.  会。 spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(取决于是否抛出runtime异常).
2.如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。
3.一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据.所以你的catch代码是画蛇添足。
seagullgao (初级程序员) 2009-05-30
sping事务的exception一般在调用该service的action中catch,然后将结果导到出错页面,告诉user出差的原因。如果你想知道详细的出错原因,可以在spring的 service中抛出自定义exception,然后在出错页面中显示不同的出错message.
seagullgao (初级程序员) 2009-06-08
SPRING2.5中,HIBERNETTEMPLATE是线程和事务绑定的,这和spring2.0不一样,现在的数据库操作基类都是2.0的,在执行数据库变更操作时候会自动执行,然而在2.5中它不会,需要手动在绑定事务的hibernetTemplate上执行flush()

你可能感兴趣的:(DAO,spring,多线程,工作)