转载:http://blog.csdn.net/z69183787/article/details/37819831

前文提到,最新换了框架,新项目用SpringMVC + Spring JdbcTemplate。搭框架时,发现了一个事务无法正常回滚的问题,记录如下:

首先展示问题:

Spring applicationContext.xml配置:

  1. <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
  2. <property name="jndiName">
  3. <value>java:comp/env/jdbc/will</value>
  4. </property>
  5. </bean>
  6. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  7. <property name="dataSource" ref="dataSource" />
  8. </bean>
  9. <bean id="txManager"
  10. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  11. <property name="dataSource" ref="dataSource" />
  12. </bean>
  13. <!-- 事务控制   -->
  14. <tx:annotation-driven transaction-manager="txManager" />

Spring mvc.dispatcher.xml配置:

  1. <!-- 自动扫描的包名 -->
  2. <context:component-scan base-package="com.will" >
  3. </context:component-scan>
  4. <!-- 默认的注解映射的支持 -->
  5. <mvc:annotation-driven />
  6. <!-- 对静态资源文件的访问  -->
  7. <mvc:default-servlet-handler/>
  8. <!-- 拦截器
  9. <mvc:interceptors>
  10. <bean class="com.will.mvc.MyInteceptor" />
  11. </mvc:interceptors>
  12. -->
  13. <!-- 视图解释类 -->
  14. <bean id="viewResolver"
  15. class="org.springframework.web.servlet.view.UrlBasedViewResolver">
  16. <property name="viewClass"  value="org.springframework.web.servlet.view.JstlView" />
  17. <property name="prefix" value="/WEB-INF/pages/" />
  18. <property name="suffix" value=".jsp" />
  19. </bean>

然后在Service层模拟了一个事务回滚的method case:

  1. @Transactional
  2. public boolean save(Person person)
  3. {
  4. for(int id: new int[]{2,3})
  5. {
  6. personDao.del(id);
  7. int j = 1/0;
  8. }
  9. return false;
  10. }

本以为大功告成,在运行save方法时,由于1/0 抛出 java.lang.ArithmeticException: / by zero  RuntimeException,导致事务回归。However,no way! So crazy~

查了下,发现Spring MVC对于事务配置比较讲究,需要额外的配置。解决办法如下:

需要在 applicationContext.xml增加:

  1. <context:component-scan base-package="com.will">
  2. <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
  3. </context:component-scan>

在 Spring mvc.dispatcher.xml增加:

  1. <context:component-scan base-package="com.will" >
  2. <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
  3. <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
  4. </context:component-scan>

由于web.xml中配置:

  1. <context-param>
  2. <param-name>contextConfigLocation</param-name>
  3. <param-value>
  4. classpath:applicationContext.xml
  5. </param-value>
  6. </context-param>
  7. <listener>
  8. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  9. </listener>
  10. <servlet>
  11. <servlet-name>dispatcher</servlet-name>
  12. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  13. <init-param>
  14. <param-name>contextConfigLocation</param-name>
  15. <param-value>classpath*:/mvc_dispatcher_servlet.xml</param-value>
  16. </init-param>
  17. <load-on-startup>1</load-on-startup>
  18. </servlet>
  19. <servlet-mapping>
  20. <servlet-name>dispatcher</servlet-name>
  21. <url-pattern>*.do</url-pattern>
  22. </servlet-mapping>

Spring容器优先加载由ServletContextListener(对应applicationContext.xml)产生的父容器,而SpringMVC(对应mvc_dispatcher_servlet.xml)产生的是子容器。子容器Controller进行扫描装配时装配的@Service注解的实例是没有经过事务加强处理,即没有事务处理能力的Service,而父容器进行初始化的Service是保证事务的增强处理能力的。如果不在子容器中将Service exclude掉,此时得到的将是原样的无事务处理能力的Service。

( update 2014.05.27  今天看见一种说法:key word =双亲上下文。不使用ContextLoaderListener监听器来加载spring的配置,改用DispatcherServlet来加载spring的配置,不要双亲上下文,只使用一个DispatcherServlet就不会出现上述问题。笔者这里未测过这个办法,因为我自己的业务需要一个extends ContextLoaderListener的selfListener,有兴趣的朋友可以自己测试下这个说法,并欢迎把测试的结果与我交流 :) )

经过以上分析,故可以优化上述配置

在 applicationContext.xml增加:

  1. <context:component-scan base-package="com.will">
  2. </context:component-scan>

在 Spring mvc.dispatcher.xml增加:

    1. <context:component-scan base-package="com.will" >
    2. <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
    3. </context:component-scan>

经过如上配置,可以发现事务控制部分,可以回滚。

另外:也不是必须运行时异常才会回滚。@Transactional  (rollbackfor=Exception.class) 这样设置的话,任何异常都可以回滚。

springmvc事务回滚失效的更多相关文章

  1. springmvc 事务回滚说明

    Spring中的@Transactional(rollbackFor = Exception.class)属性详解 序言 今天我在写代码的时候,看到了.一个注解@Transactional(rollb ...

  2. springmvc mybatis 声明式事务管理回滚失效,(checked回滚)捕捉异常,传输错误信息

    一.知识点及问题 后端框架: Spring .Spring mvc .mybatis 业务需求: client先从服务端获取用户大量信息到client,编辑完毕之后统一Post至服务端,对于数据的改动 ...

  3. (转)spring异常抛出触发事务回滚策略

    背景:在面试时候问到事务方法在调用过程中出现异常,是否会传递的问题,平时接触的比较少,有些懵逼. spring异常抛出触发事务回滚策略 Spring.EJB的声明式事务默认情况下都是在抛出unchec ...

  4. Spring-Java事物回滚失效处理

    spring-Java事物回滚失效处理最近在做项目中,无意间发现有个类在抛事物回滚操作,数据也正常的插入到数据库当中了,于是仔细查看看一下具体原因. 一切还是要从Java的检查型异常和非检查型异常说起 ...

  5. SQL 事务回滚

    事务(Transaction)是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.通过事务,SQL Server能将逻辑相关的一组操作绑定在一起,以便服 ...

  6. Spring异常抛出触发事务回滚

    Spring.EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚 /** * 如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*) ...

  7. 【Java EE 学习 19】【使用过滤器实现全站压缩】【使用ThreadLocal模式解决跨DAO事务回滚问题】

    一.使用过滤器实现全站压缩 1.目标:对网站的所有JSP页面进行页面压缩,减少用户流量的使用.但是对图片和视频不进行压缩,因为图片和视频的压缩率很小,而且处理所需要的服务器资源很大. 2.实现原理: ...

  8. SqlServer事务回滚(2)

    SQL Server 2008中SQL应用系列--目录索引 SQL事务 一.事务概念    事务是一种机制.是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行.因此事务是 ...

  9. jfinal 基本应用 --事务回滚

    事务回滚 1.当时需要用到事务回滚,但是看到网上只有问题,没有真实的到底怎么用法. 2.我看了一下文档,结合了网上的大神的博客. 第一种方法: Db.tx(new IAtom(){ @Override ...

随机推荐

  1. Linux 搭建FTP

    Linux 搭建FTP 步骤一:安装 vsftpd 1,运行以下命令安装 vsftpd. yum install -y vsftpd 出现下图表示安装成功. 2,打开etc/vsftpd cd /et ...

  2. 添加用户到 sudo

    sudo 简介: 在 Linux 中系统管理员可以通过 sudo 实用程序让用户或组能够作为另一个用户运行命令.换句话说,可以分派命令特权,而不需要另一个用户的密码.root 用户通过在 /etc/s ...

  3. Adobe9阅读器渗透攻击——20145301

    Adobe9阅读器渗透攻击 实验步骤: 在kali终端中开启msfconsole,输入命令use exploit/windows/fileformat/adobe_cooltype_sing,进入该漏 ...

  4. VC++使用IMAPI调用Outlook邮箱客户端和Foxmail邮箱客户端遇到的问题

    http://www.cnblogs.com/abiao/articles/303090.html 发送邮件 MAPISendMail() 发送邮件功能就是对MAPISendMail()的封装.下面解 ...

  5. Git基础 —— Github 的使用

    Git 基础学习系列 Git 基础 -- 安装 配置 别名 对象 Git 基础 -- 常用命令 Git 基础 -- 常见使用场景 Git基础 -- Github 的使用 Github 的利用 Gith ...

  6. win10中mount和unmount iso文件

    https://www.windowscentral.com/how-mount-or-unmount-iso-images-windows-10 You can also right-click t ...

  7. LR学习资料

    http://ajita.iteye.com/blog/1728243/ 选择哪种方式录制,有以下参考原则: 1 基于浏览器的应用程序推荐使用HTML-based Script 2 不是基于浏览器的应 ...

  8. XML序列化、反序列化

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Run ...

  9. hdu 5493 Queue 树状数组第K大或者二分

    Queue Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  10. go 接口

    1. package main import ( "fmt" ) type Phone interface { call() } type NokiaPhone struct { ...