springAOP事物管理不生效原因总结————转载收藏于: superdog007

环境:mybatis3.3,spring3.2,druid

我是将事物交给springAOP进行管理,采用的xml方式配置,同时开启支持注解式事物驱动。


	<!-- 下面是配置声明式事务管理的,个人感觉比用注解管理事务要简单方便 -->
	<bean id="txManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="OracledataSource"></property>
	</bean>
	<!-- 定义事务传播属性 --> 
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="save*" propagation="REQUIRED"
				rollback-for="Exception" />
			<tx:method name="insert*" propagation="REQUIRED"
                rollback-for="Exception" />	
			<tx:method name="update*" propagation="REQUIRED"
				rollback-for="Exception" />
			<tx:method name="remove*" propagation="REQUIRED"
				rollback-for="Exception" />
			<tx:method name="delete*" propagation="REQUIRED"
				rollback-for="Exception" />
			<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
			<tx:method name="get*" read-only="true" />
			<tx:method name="find*" read-only="true" />
			<tx:method name="list*" read-only="true" />
			<tx:method name="*" rollback-for="Exception" />
		</tx:attributes>
	</tx:advice>
	
    <!-- proxy-target-class="true" 解决spring自动注解不能自动动态转换接口类成实现类的问题;
    默认状态下,proxy-target-class属性的值为false,
    那么被代理类是基于javaSE(JDK)的动态代理(一般被代理类会实现接口);
    如果显式的设置了proxy-target-class属性的值为true,
    那么被代理类就将基于cglib动态代理(spring框架中的代理)-->
	<aop:config proxy-target-class="true">
		<!-- 管理事务操作 说明在这个包中的这些类中的这些方法应用前面 txAdvice 的配置事务传播属性-->
		<aop:advisor pointcut="execution(* com.erp.*.service..*.*(..))"
			advice-ref="txAdvice" />
	</aop:config>
	
   <!-- 把扫描Service的配置放在配置事务的后面而不是SpringMVC的配置中主要是避免配置文件的加载顺序
	先加载SpringMVC后加载这儿这个配置文件导致 事务不起作用 -->
    <!-- 配置spring扫描所有Service和Repository组件自动装配 -->
    <!--自动扫描含有@Service将其注入为bean -->
    <context:component-scan base-package="com.erp.*.service" />
    <!--自动扫描含有@Repository将其注入为bean -->
    <context:component-scan base-package="com.erp.*.dao" />
    
配置方式很多,具体大家可以去网上查找,此处就不赘述了,这里之说下可能造成事物失效的原因:

前提是你的事物配置不会出现基本的错误,如excution表达式的错误,导致不能正确的注入事物,以及advice中指定注册的事物管理bean等

一:想必大家都用了springMVC,并且使用了其扫描器组件,对项目中加入servcie /ctroller注解的bean进行注册交给srping容器管理,在springMVC配置文件中我们只扫描ctroller对所有的service进行过滤掉,因为按照spring配置文件的加载顺序来讲,先加载springmvc配置文件,再加载spring配置文件,我们的事物一般都在srping配置文件中进行配置,如果此时在加载srpingMVC配置文件的时候,把servlce也给注册了,但是此时事物还没加载,也就导致后面的事物无法成功注入到service中。所以把对service的扫描放在spring配置文件中或是其他配置文件中。

二:如果以上步骤都没问题,事物还是失效,查看事物配置中的excution表达式路径是否正确,查看rollback-for指定的异常类是否有,通过Log4j ,debug模式将事物日志打印出来,在方法中手动new一个异常抛出(throw new RuntimeException())看是否事物回滚了,注意异常抛出要在service层

三:如果你用了mysql数据库,查看数据库存储引擎,MyISAM是不支持事物的,需要改成InnoDB

四:如果Service中有方法间的调用当且使用cglib动态增强aop时,注意每个方法都声明了事务。
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页