在一个项目中,用户注册的时候需要同时插入两张表,一张是User表,一张是Orgnize表,出现这种情况:在插入orgnize表的时候出现异常但是User表已经插入数据了,我想要的是这两张表的数据同时插入,当出现异常的时候进行回滚,这是我的spring中的事务管理的配置:
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="baseTransaction"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager" />
<property name="proxyTargetClass" value="true" />
<property name="transactionAttributes">
<props>
<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
这种情况我如何进行管理呢?

解决方案 »

  1.   

    在程序中你可以把一组操作交给一个session会话来处理,如果异常则回滚,否则提交。这样就可以了。
      

  2.   

    没有粘贴关键的部分:进行数据库操作的Service类的代码和配置
      

  3.   

    这是插入操作的实现:
    public void insertAccount(AccountTable account) {
    getHibernateTemplate().save(account);
    } public void insertOrg(OrgTable orgTable) {
    getHibernateTemplate().save(orgTable);
    }
    由于注册的时候有两种方式:个人或者公司,所以这两个插入操作不能放在一起。
    service的配置如下:
    <bean id="userDao" parent="baseTransaction" abstract="false"
    lazy-init="default" autowire="default" dependency-check="default">
    <property name="target">
    <bean
    class="cn.legend.znt.dao.hibernate.UserDaoHibernate">
    <property name="sessionFactory">
    <ref bean="sessionFactory" />
    </property>
    </bean>
    </property>
    </bean>
    至于说的用session会话来处理,如果异常则回滚,否则提交,在用事务处理了,怎么用session,不是很明白,能否举个例子。
      

  4.   

    给你个片段,你没贴最关键的部分。 <bean id="baseTxProxy" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager">
                    <ref bean="transactionManager"/>
            </property>
            <property name="transactionAttributes">
                    <props>
                            <prop key="save*">PROPAGATION_REQUIRED,-Throwable</prop>
                            <prop key="remove*">PROPAGATION_REQUIRED,-Throwable</prop>
                            <prop key="add*">PROPAGATION_REQUIRED,-Throwable</prop>
                            <prop key="*TM">PROPAGATION_REQUIRED,-Throwable</prop>
                    </props>
            </property>
    </bean>
        <bean id="mailServer" parent="baseTxProxy">
         <property name="target">
         <bean class="com.syj.server.impl.MailServerImpl" parent="baseServer"/>
         </property>
    </bean>
      

  5.   

    用我的例子来说明
    在MailServerImpl里面有个
    addXX方法调用你的dao的
    insertAccount
    和insertOrg
      

  6.   

    有业务方法没 
    有的话 事务就代理业务方法 
    在 业务方法里调用dao层的两个方法 可以实现回滚
    比如
    业务方法
    public boolean insert(User user,Orgnize orgnize){
       try{
          userDao.insert(user);
         orgnizeDao.insert(orgnize);
       }catch(Exception e){
         ...
       }
    }
    然后配置文件代理这个业务类就可以了
      

  7.   

    楼主和楼下别像楼上那么写,异常被吃掉了还靠什么回滚了
    在有try catch机制的语言里面强烈不建议使用boolean来判断成败与否
    另外这里还有异常处理的隐患,catch了后没什么也没干只是输出了下,没有异常链,真正的大程序里面会导致严重的问题
    是与try catch机制相违背的。
      

  8.   

    首先非常感谢sunyujia的恢复,你贴出来的关键部分其实我已经贴出来了,<bean id="userDao" parent="baseTransaction" abstract="false" 
    lazy-init="default" autowire="default" dependency-check="default"> 
    <property name="target"> 
    <bean 
    class="cn.legend.znt.dao.hibernate.UserDaoHibernate"> 
    <property name="sessionFactory"> 
    <ref bean="sessionFactory" /> 
    </property> 
    </bean> 
    </property> 
    </bean>
    偷懒没有再userservice这么写,可是即使你在xxserviceImpl中定义了addXX方法调用你的dao的 
    insertAccount 
    和insertOrg ,那么假如调用insertOrg()时出现了异常,怎么回滚insertAccount()里面的事务呢?
      

  9.   

    回滚是自动的,在spring里面做的,网上有很多人发博客贴出了 spring这个过程的源码。
    <prop key="add*">PROPAGATION_REQUIRED,-Throwable</prop>
    这就表示在add开头的方法中如果有Throwable异常则回滚事务,
    Throwable异常是所有异常的父类,即有异常即回滚了
    不用编程,这个被称为声明式事务。按我说的做就行了。我的一篇帖子也可以说明spring的实现原理
    有兴趣的话可以看看
    http://blog.csdn.net/sunyujia/archive/2008/06/01/2500684.aspx
      

  10.   

    spring倡导的是基于业务层面的事务处理,你现在想的是传统的事务处理方式,
    因为传统的事务处理不好,你才会来这问的,是吧。呵呵
    xserver 的x方法里面调dao做业务有异常x方法内的所有事务回滚,这不是很好吗
    xserver 要被spring进行 动态代理才行,所以依靠xml来配置,因为动态代理不需要类本身做什么。它是一种aop你再看我发的xml
      

  11.   

    业务逻辑写在service里面,到时候配置service的事务,这样好多了,不要配置到dao层,MyEclipse自动生成的dao都没给你加事务,就是要让你在
    service里面写业务逻辑,这样就能让dao层和逻辑层分开了,你这样处理的思路有点问题。
      

  12.   

    几个点在service同一方法中调用两个dao操作
    将service的这个方法配置事务
    service方法不要try catch让spring去捕获并处理
    dao用jdbc时不要autosubmit