使用spring+springMVC 组合开发,声明式事务失效

在整合springMVC+ibatis+spring框架时采用的是声明式事务,代码写完后故意测试了一下事务是否生效,写了一个测试方法: 
Java代码   收藏代码
  1. public int[] delAndUpdate()  {  
  2.         int a = testDao.delCart();  
  3.         int c = testDao.insertCart();  
  4.         int b = testDao.updateCart();  
  5.         int[] count = new int[] { a, c, b };  
  6.         return count;  
  7.     }  

有增删改三种操作类型,最后一个update操作时候故意把sql写错,在执行时候就会抛出异常,再通过查看数据库看前两条数据是否删除和插入,杯具的是事务竟然没回滚,以为配置写的有问题
Java代码   收藏代码
  1. <!--声明式事务控制  -->  
  2.     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  3.         <property name="dataSource" ref="dataSource"/>  
  4.     </bean>  
  5.       
  6.     <!-- 指定事务切入点 -->  
  7.      <aop:config>  
  8.         <aop:pointcut id="serviceOperation" expression="execution(* cn.myshop.service.*.*(..))" />  
  9.         <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice" />  
  10.     </aop:config>  
  11.        
  12.     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  13.         <tx:attributes>  
  14.             <!-- 读取数据方法,一般采用只读事务-->  
  15.             <tx:method name="get*" read-only="true"/>  
  16.             <tx:method name="query*" read-only="true"/>  
  17.             <tx:method name="find*" read-only="true"/>  
  18.             <tx:method name="load*" read-only="true"/>  
  19.               
  20.             <!--以下方法,如save,update,insert等对数据库进行写入操作的方法,当产生Exception时进行回滚 -->  
  21.             <tx:method name="insert*"   />  
  22.             <tx:method name="update*"  />  
  23.             <tx:method name="save*"  />  
  24.             <tx:method name="add*"  />  
  25.             <tx:method name="create*"  />  
  26.             <tx:method name="del*"  />  
  27.             <tx:method name="remove*"  />  
  28.             <tx:method name="batchCommit*"  />  
  29.             <!-- <tx:method name="*" rollback-for="Exception"/> -->  
  30.         </tx:attributes>  
  31.     </tx:advice>  


经仔细查看和网上的配置对比,发现没什么问题,实在想不到什么地方有问题,之后google了半天,造成声明式事务无效不回滚的原因主要有几个(事务配置错了就不说了): 
1、由于数据库为mysql,网上有说法是,
Java代码   收藏代码
  1. mysql默认存储引擎为MyISAM是不支持事务的,  
  2. 需要设置为InnoDB模式,通过show engines; 命令看到  

 
InnoDB已经是默认的存储引擎,查看操作的表 


也为InnoDB模式,又看了my.ini中的配置 
Java代码   收藏代码
  1. default-storage-engine=INNODB  
  2. .......  
  3. #skip-innodb  
都没问题,看来是其它地方的问题了。 

2、另一种说法,不太相信,说是Spring的声明式事务需要抛出RuntimeException后才会触发事务的回滚,是这样吗,添加抛出RuntimeException依然没回滚,对于抛出RuntimeException事务才生效说法只能是一连串疑问了。 

3、英语不杂地,官方文档也只能沉睡了,无奈继续google,最后在iteye上看到一帖子同为事务不生效 http://www.iteye.com/topic/1123069  
其中有一兄弟的回帖:
Java代码   收藏代码
  1.  1.root-context.xml   
  2. <!-- 不扫描带有@Controller注解的类。因为这些类已经随容器启动时,在servlet-context中扫描过一遍了 -->   
  3. <context:component-scan base-package="com.kimho">   
  4. <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   
  5. </context:component-scan>   
  6.   
  7. 2、servlet-context.xml:   
  8. <!-- 扫描业务组件,让spring不扫描带有@Service注解的类(留在root-context.xml中扫描@Service注解的类),防止事务失效 -->   
  9. <context:component-scan base-package="com.kimho">   
  10. <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>   
  11. </context:component-scan>   
同样我也使用的spring注解+springMVC注解,默认情况下spring应该先加载applicationContext.xml,之后再加载springMVC-servlet.xml,按那兄弟说法可能会造成事务失效。 
我的springMVC-servlet.xml配置如下 
Java代码   收藏代码
  1. <mvc:annotation-driven />  
  2.     <context:component-scan base-package="cn.myshop"/>  
而applicationContext.xml没有再配置component-scan,本以为spring和springMVC同根生,使用同一个component-scan即可,没想到还相煎甚急,那就修改配置测试一下。springMVC-servlet.xml修改为: 
Java代码   收藏代码
  1. <mvc:annotation-driven />  
  2. <context:component-scan base-package="cn.myshop">  
  3.     <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>   
  4. </context:component-scan>  


applicationContext.xml中添加 
Java代码   收藏代码
  1. <context:component-scan base-package="cn.myshop"/>   

重启tomcat,测试  事务正常回滚,还真是这个原因,另外也不需要抛出RuntimeException。 
看来如果项目采用spring、 springMVC的注解方式这个地方确实该注意,如果使用其它架构或者不使用注解的方式,应该就不会有这样的问题。 


附加:使用powerdedigner生成表建表sql后,执行到mysql,用nvaicat for mysql查看表字段的中文注释乱码了,而直接用navicat修改字段注释不乱码,powerdesigner导出时也选择的为utf-8,看来是mysql在执行脚本时乱码了,查看mysql的my.in文件发现默认编码为default-character-set=latin1 不知什么编码,那就改为default-character-set=utf8,重启服务再执行脚本,没有乱码了。 (注意default-character-set=latin1 共有两个地方,都改为utf8)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值