`
caizi12
  • 浏览: 174953 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用spring声明式事务失效之第二弹

阅读更多
   最近又在搭一个新的开发框架,并把阿里的dubbo服务化框架集成了进来,集成ok后并配置了声明式事务,但测试结果是不会回滚。
测试代码如下
    public boolean addUser(SysUser user) throws Exception {
		dubboTestDao.addUser(user);

		SysUser sysUser = new SysUser();
		dubboTestDao.addUser(sysUser);
		
		return true;
	}

  


事务配置和之前的项目配置方法一样,执行junit测试并抛出异常,查询数据库,却查到新加了一条数据 ,事务配置如下
		<!--声明式事务控制  -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 指定事务切入点  凡是实现了以cn.frame打头的包及其子包里以Service结尾接口中的所有方法需要由事务进行控制-->
	<aop:config>
		<aop:pointcut id="serviceOperation" expression="execution(* com..*Srv.*(..))" />
		<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice" />
	</aop:config>
	 
 	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
		    <!-- 读取数据方法,一般采用只读事务-->
			<tx:method name="get*" read-only="true"/>
			<tx:method name="query*" read-only="true"/>
			<tx:method name="find*" read-only="true"/>
			<tx:method name="load*" read-only="true"/>
			
			<!--等其它增删改数据操作,当产生Exception时都进行回滚 -->
			<tx:method name="*" propagation="REQUIRED" /> 
		</tx:attributes>
	</tx:advice>

仔细看了配置,并排除了因springmvc与spring使用注解扫描同一个包导致事务失效原因后也没发现什么问题,之后不停的进行尝试,并进行修改代码,
public boolean addUser(SysUser user) throws Exception {
		dubboTestDao.addUser(user);

		SysUser sysUser = new SysUser();
		dubboTestDao.addUser(sysUser);
		if(1==1)throw new Exception();
		return true;
	}
  

依然没有回滚,后看到网上有说spring声明式事务只捕获到RuntimeException异常才能回滚事务随修改为throw new RuntimeException();事务果然能正常回滚,但为什么不添加这行代码
if(1==1)throw new Exception();
就不会回滚呢,同样都是抛出异常,唯一不一样的也就是炮出的异常类型不一样,项目中用的ibatis,由于是新new的一个对象没有设置属性就进行insert,肯定会抛异常,查看异常类型是
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException
并查看了该类的父类一层一层往上查,该类最上面继承的是"SqlException>Exception",并没有继承RuntimeException,到此也就明白了问题所在,由于数据的问题抛出的异常类型是没有继承RuntimeException,因此spring也就不能正确的进行捕获并处理事务进行回滚, 这个问题看来之前没注意啊,之前给的感觉是任何异常都可以进行回滚,之前的测试类可能正好抛出的是RuntimeException类异常而没发现问题所在。

到此问题原因都知道了,那如何修改呢,有人说都抛出RuntimeException不就ok了吗,或许是一种方法,我的方法是修改配置,修改为:
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>

只要出现Exception就进行回滚。
这个问题查来查去最后只加了一个配置就解决了,解决过程有点曲折,从侧面也反映出对spring的事务管理这方面知识缺乏一定的深度及全面性。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics