直接上代码。
ClassA{
    updateA(){
       updateAthao()       // 调用B的save
       ClassB.saveB();
       // 调用C的save
       ClassC.saveC();
    }
    updateAthao(){
        // 修改表数据
    }}ClassB{
   saveB(){
     // 其它修改操作
     for (){
       查询表B
       修改表B
     }
   }
}ClassC{
   saveC(){
     throw Exception();
   }
}action类调用ClassA.saveA()。
ClassB.saveB多次查询并修改表B的数据。
当ClassC.saveC()抛出异常时,ClassA.updateAthao()中修改的数据全部回滚。
ClassB.saveB()中只有循环中最后一次修改的数据回滚,其它全部提交经过调试后发现这是因为hibernate为避免出现脏数据,所以在查询后修改数据再查询同一表的数据时会将之前的事务全部提交。有一个办法可以解决就是查询不在循环中进行,只要先查询后修改,就不会有问题。
但是这个方法不太好,有没有办法让循环中的操作也和其它修改一样和ClassA中的操作一起回滚呢。

解决方案 »

  1.   

    我的事务配置如下:
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
    <ref bean="sessionFactory"/>
    </property>
    </bean>


    <!-- 配置事务的传播特性   -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    <tx:method name="save*" propagation="REQUIRED"/>
    <tx:method name="change*" propagation="REQUIRED"/>
    <tx:method name="add*" propagation="REQUIRED"/>
    <tx:method name="del*" propagation="REQUIRED"/>
    <tx:method name="modify*" propagation="REQUIRED"/>
    <tx:method name="update*" propagation="REQUIRED"/>
    <tx:method name="create*" propagation="REQUIRED"/>
    <tx:method name="audit*" propagation="REQUIRED"/>
    <tx:method name="init*" propagation="REQUIRED"/>
    </tx:attributes>
    </tx:advice>    数据库是mysql
      

  2.   

    1、你上面写的乱哄哄的,只看到了updateA,没有看到saveA。
    2、我不知道你saveB中是如何循环与db交互的,就比如,你查询一笔,修改一笔。saveB整个应该算是2个原子操作吧。这是dao层的,你dao层首先加上事物,然后,在一个方法中操作多个原子操作的时候,确保一个成功后,再执行下一个,并且,如果是循环的存取,应该设置一个标记flag,除非所有saveB都执行ok,flag = true,否则,只要有一笔失败,全部失败。这样,就到了service层,service层加上了事物。同样,对于数据库的多个原子操作,也类似这样的做法。这样应该就不会出现脏数据。如果有可能出现,那也应该是多线程情况下出现的。
      

  3.   

    没有说清楚,这里写的就是service层的操作,
    action类调用classA.updataA();updataA调用ClassB.savaB()和ClassC.savaC().
      

  4.   


    你要给dao 和 service层都加上事物。savaB中,确保可以正常回退
      

  5.   

    又找到一种方法就是将查询出来的对象转化脱管态再操作就没有问题,就是不知道能不能配置对象只在dao层是持久态
      

  6.   


    瞬时态 (Transient)、持久态(Persistent)、脱管态(Detached)那瞬时态也就是ok的?
      

  7.   


    我觉得跟那个没有关系,本身从数据库查询出来的都是持久状态的。
    是否有必要再转成游离状态,是需要评估一下。不过,你再从事物的角度去看看,特别是dao层的事物。