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

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

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

有增删改三种操作类型,最后一个update操作时候故意把sql写错,在执行时候就会抛出异常,再通过查看数据库看前两条数据是否删除和插入,杯具的是事务竟然没回滚,以为配置写的有问题
<!--声明式事务控制  -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 指定事务切入点 -->
	 <aop:config>
		<aop:pointcut id="serviceOperation" expression="execution(* cn.myshop.service.*.*(..))" />
		<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"/>
			
			<!--以下方法,如save,update,insert等对数据库进行写入操作的方法,当产生Exception时进行回滚 -->
			<tx:method name="insert*"   />
			<tx:method name="update*"  />
			<tx:method name="save*"  />
			<tx:method name="add*"  />
			<tx:method name="create*"  />
			<tx:method name="del*"  />
			<tx:method name="remove*"  />
			<tx:method name="batchCommit*"  />
                 <!--2015-03-11,修改为抛出异常都进行回滚 -->
			<tx:method name="*" rollback-for="Exception"/> 
		</tx:attributes>
	</tx:advice>


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


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


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

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

3、英语不杂地,官方文档也只能沉睡了,无奈继续google,最后在iteye上看到一帖子同为事务不生效http://www.iteye.com/topic/1123069
其中有一兄弟的回帖:
 1.root-context.xml 
<!-- 不扫描带有@Controller注解的类。因为这些类已经随容器启动时,在servlet-context中扫描过一遍了 --> 
<context:component-scan base-package="com.kimho"> 
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 
</context:component-scan> 

2、servlet-context.xml: 
<!-- 扫描业务组件,让spring不扫描带有@Service注解的类(留在root-context.xml中扫描@Service注解的类),防止事务失效 --> 
<context:component-scan base-package="com.kimho"> 
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> 
</context:component-scan> 
同样我也使用的spring注解+springMVC注解,默认情况下spring应该先加载applicationContext.xml,之后再加载springMVC-servlet.xml,按那兄弟说法可能会造成事务失效。
我的springMVC-servlet.xml配置如下
<mvc:annotation-driven />
	<context:component-scan base-package="cn.myshop"/>
而applicationContext.xml没有再配置component-scan,本以为spring和springMVC同根生,使用同一个component-scan即可,没想到还相煎甚急,那就修改配置测试一下。springMVC-servlet.xml修改为:
	<mvc:annotation-driven />
	<context:component-scan base-package="cn.myshop">
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> 
	</context:component-scan>


applicationContext.xml中添加
<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)
  • 大小: 29.7 KB
  • 大小: 57 KB
分享到:
评论
8 楼 caizi12 2017-09-27  
NQ1114195029 写道
我的还是没有解决,能请您帮我看下什么原因吗?


看看配置
7 楼 NQ1114195029 2017-08-23  
我的还是没有解决,能请您帮我看下什么原因吗?
6 楼 huzhupo 2016-11-04  
我也是这个原因,按照帖子说法修改成功,感谢!
5 楼 cuisuqiang 2015-04-30  
可以参考http://javacui.com/framework/187.html 如果你要在Controll而里面做事物管理,那要加一个配置
4 楼 maoruiwen 2014-07-16  
明天去公司测试一下。。。唉。看到大家都成功了。。我觉得我距离成功不远了。。
3 楼 caizi12 2014-07-07  
远方_张涛 写道
太感谢了,真的是这个原因,按照帖子的说法修改成功 

2 楼 远方_张涛 2014-07-03  
太感谢了,真的是这个原因,按照帖子的说法修改成功 
1 楼 hzaupj 2014-05-07  
终于找到原因了,感谢一下

相关推荐

    声明式事务失效的方法

    声明式事务失效的方法 在 Spring 框架中,声明式事务是指通过配置文件或注解来定义事务边界的方式。这种方式可以使得事务管理变得更加灵活和可靠。但是,在使用 Spring+SpringMVC 组合开发时,声明式事务可能会失效...

    Spring+SpringMVC配置事务管理无效原因及解决办法详解

    编程式事务管理需要手动编写事务管理代码,而声明式事务管理使用注解或 XML 配置来管理事务。 Spring+SpringMVC 配置事务管理无效原因 在使用 Spring 和 SpringMVC 配置事务管理时,可能会遇到事务管理无效的问题...

    16.spring与springmvc常见面试题.docx

    "spring与springmvc常见面试题" Spring 是一个流行的 Java Web 应用框架,提供了 ...(不推荐使用)2、声明式事务,在配置文件中配置(推荐使用)声明式事务又分为两种:基于注解的声明式事务和基于 XML 的声明式事务。

    Spring-Reference_zh_CN(Spring中文参考手册)

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.6.1. @Transactional 有关的设置 ...

    springMVC AOP拦截拦截Controller等实现日志管理

    在Spring MVC中,AOP(面向切面编程)是一种强大的工具,可以让我们在不修改代码...综上所述,Spring MVC结合AOP为我们提供了一种优雅的方式,以声明式地管理和记录Controller层的日志,增强了系统的可观察性和稳定性。

    SSM中事务管理所需的jar包-aspectjweaver

    在Java Web开发中,SSM(Spring、SpringMVC、MyBatis)是一个常见的框架组合,用于构建高效、灵活的企业级应用。其中,事务管理是确保数据一致性与完整性的关键部分。`aspectjweaver.jar`是AspectJ库的一个组成部分...

    (2024)跳槽涨薪必备精选面试题.pdf

    - Spring 使用 AOP 和声明式事务管理。 - 支持多种事务管理器,如 JTA、JDBC、Hibernate 等。 7. **Spring容器启动流程** - 加载配置文件。 - 创建 BeanFactory。 - 注册后处理器。 - 初始化 Bean。 8. **...

    跳槽涨薪涨薪必备精选面试题.pdf

    Spring Cloud组件如Zuul(API网关)、Feign(声明式服务调用)等,与Dubbo相比更注重整体微服务生态。 以上只是部分面试题目的解析,实际面试中,面试官可能会结合具体项目经验和技术深度进行深入探讨。程序员在...

    java面试知识

    - **实现方式**:懒汉式、饿汉式、双重检查锁定等。 ##### 解析XML文件的几种技术 - **DOM (Document Object Model)**:将XML文档转化为树形结构。 - **SAX (Simple API for XML)**:基于事件驱动模型。 - **StAX ...

Global site tag (gtag.js) - Google Analytics