情况是这样的 :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>
问题一:现在换成 控制层调用->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>
要配置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事务必须面向接口) -->
至于为什么么要把代理模式彻底搞懂就明白了。
还有就是在service层里面,我总要处理一些逻辑代码,就比如test就是处理逻辑代码的,那么在处理同时也需要对持久层进行操作,那就是test也要加事务?
是的,test要加事务,如果你的test的方法跟saveUser updateUser 不在同一个类里面的话,那test方法没有事务也是可以成功的。在同一个类里面内部调用的只有入口方法的事务才有效。这个一下说不清,搞懂代理模式应该能明白。
我上面配置的事务是已save开头、update开头的,当然service层方法还有更多的其他业务逻辑的方法,而这些逻辑的方法就会用到一些save、update开头的方法,那那些方法都需要加上事务,你们在实际项目应用中也是这样吗?如果是这样的话,那完全可以就用 * 来表示所有的方法都加上事务,不需要在指定什么开头了