情况是这样的 :spring MVC 有个service类,分为三个方法 saveUser()、updateUser()、test() ,在控制层调用->updateUser( 更新表)->调用saveUser(); 如果saveUser()会抛出主键已存在,此时事务回滚,属正确.
问题一:现在换成  控制层调用->test() ->该方法调用了updateUser()-> 该方法调用了 saveUser()方法,如果saveUser抛出主键已存在,此时事务未回滚   求解
问题二:大家是怎么配置事务的,如果采用全注解的话,是不是在开发过程中,需要用到事务的时候在手工到每个方法上加上事务,这样是不是很多service的方法都要加了
XML 配置文件
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource"><ref bean="dataSource"/></property>
    </bean> <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="update*" propagation="REQUIRED" rollback-for="SQLException"/>
<tx:method name="save*" propagation="REQUIRED" rollback-for="SQLException"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:config>
<aop:advisor pointcut="execution(* com.base.service.impl..*.*(..))"   advice-ref="transactionAdvice"/>
</aop:config>

解决方案 »

  1.   


    要配置spring声明式事物就可以了
    1.首先修改spring配置文件的头部让其支持AOP
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    2.配置事务管理器
    <bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource">
    <ref bean="dataSource" />
    </property>
    </bean>
    3.配置事务的通知
    <!-- 每个method配置是目标对象中连接点的描述,例如以do, get,del,add开头的方法会自动添加事务 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    <tx:method name="add*" propagation="REQUIRED"
    rollback-for="Exception" />
    <tx:method name="update*" propagation="REQUIRED"
    rollback-for="Exception" />
    <tx:method name="del*" propagation="REQUIRED"
    rollback-for="Exception" />
    <tx:method name="*" propagation="SUPPORTS" read-only="true" />
    </tx:attributes>
    </tx:advice>
    4. 事务代理
    <aop:config>
    <aop:pointcut id="allManagerMethod"
    expression="execution(* com.aegon_cnooc.oa..service.impl.*ServiceImpl.*(..))" />
    <aop:advisor advice-ref="txAdvice"
    pointcut-ref="allManagerMethod" />
    </aop:config>
    <!-- 注意:被注入的目标对象假如向拥有事务,必须有接口(AOP事务必须面向接口) -->
      

  2.   

    test方法有加事务么?test方法如果没事务的话那是不会回滚的。  
    至于为什么么要把代理模式彻底搞懂就明白了。
      

  3.   

    test方法要加事务?我只加了这句<tx:method name="*" propagation="SUPPORTS" read-only="true"/> 
    还有就是在service层里面,我总要处理一些逻辑代码,就比如test就是处理逻辑代码的,那么在处理同时也需要对持久层进行操作,那就是test也要加事务?
      

  4.   


    是的,test要加事务,如果你的test的方法跟saveUser updateUser 不在同一个类里面的话,那test方法没有事务也是可以成功的。在同一个类里面内部调用的只有入口方法的事务才有效。这个一下说不清,搞懂代理模式应该能明白。
      

  5.   

    <tx:method name="*" propagation="SUPPORTS" read-only="true"/> 要改成 REQUIRED吧,readony要去掉
      

  6.   

    恩,这样的话是会回滚的,那也就是说我 控制层->service层->持久层
    我上面配置的事务是已save开头、update开头的,当然service层方法还有更多的其他业务逻辑的方法,而这些逻辑的方法就会用到一些save、update开头的方法,那那些方法都需要加上事务,你们在实际项目应用中也是这样吗?如果是这样的话,那完全可以就用 * 来表示所有的方法都加上事务,不需要在指定什么开头了
      

  7.   

    能否说说你们事务是怎么配置的,像service层很多方法,如果按照我上面那种配置的话,如果说service有操作持久层的话且需要在一个事务里面的话就要按照上面配置的按那个去命名方法,反之,则不需要
      

  8.   

    目前使用 annotation方式的事务申明,需要则加,无需就不加