欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-14 17:11:56
...
   最近又在搭一个新的开发框架,并把阿里的dubbo服务化框架集成了进来,集成ok后并配置了声明式事务,但测试结果是不会回滚。
测试代码如下
    public boolean addUser(SysUser user) throws Exception {
		dubboTestDao.addUser(user);

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

  


事务配置和之前的项目配置方法一样,执行junit测试并抛出异常,查询数据库,却查到新加了一条数据使用spring声明式事务失效之第二弹
            
    
    博客分类: spring spring声明式事务失效 ,事务配置如下
		<!--声明式事务控制  -->
    <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也就不能正确的进行捕获并处理事务进行回滚,使用spring声明式事务失效之第二弹
            
    
    博客分类: spring spring声明式事务失效 这个问题看来之前没注意啊,之前给的感觉是任何异常都可以进行回滚,之前的测试类可能正好抛出的是RuntimeException类异常而没发现问题所在。

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

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