解决基于SpringMVC+MYSQL注解@Transaction事务无效问题


##########################万能分割线#########################

最近在使用springmvc结合mysql开发时候,遇到一个问题,基于注解的事务配置在程序运行中事务无效,即不进行事务回滚。下面说说如何解决该问题......

               (现在常规MySQL都是使用INNODB存储引擎,即都是支持事务的)

############################################################


<1>代码块:[service层的staffService.java]

        @Transactional(rollbackFor = Exception.class)
	public Map<String,Object> deleteStaffByIds(Long currentStaffId,List<Long> staffsidList,List<Long> merchantsId,Long cityId) throws Exception {
		......
		try {
		
			//删除人员商户表信息
			staffDao.deleteStaffMerchant(staffsidList,merchantsId);
			//删除人员角色表信息
			staffDao.deleteStaffRole(staffsidList);
			//删除人员城市表信息
			staffDao.deleteStaffCity(staffsidList,cityId);
		
		} catch (Exception e) {
			log.error("关联删除人员信息失败,失败信息: "+e.getMessage());
			logService.insertWebLog(currentStaffId, sOperateClass, sMethodName, "失败",retMesg);
			throw e;
		}
        ....
	}

上述代码块使用了基于@Transaction注解事务进行回滚设置,测试设置:使得在删除deleteStaffMerchant、deleteStaffRole方法成功后,设置最后的deleteStaffCity方法在执行操作数据库时候跑出异常,正常情况即事务回滚的情况下,前面两个方法删除的记录会恢复,进行事务回滚。但是在测试时候发现并没有执行事务回滚。

之后,检查了配置文件:

<2>applicationContext.xml配置:

	<!-- 设置需要进行Spring注解扫描的类包 -->
	<context:component-scan base-package="com.xianSky" />
	<!-- 配置事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
		p:dataSource-ref="dbDataSource"></bean>
	<!-- 注解事务 -->
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
数据库连接池与事务管理器,注解扫描都没有问题....之后又查看了springMVC配置文件


<3>springMVC-servlet.xml配置:

    <!-- 当我们需要controller返回一个map的json对象时,可以设定<mvc:annotation-driven /> -->
    <mvc:annotation-driven /> 
	<!-- 设置需要进行Spring注解扫描的类包 -->
	<context:component-scan base-package="com.xianSky" />
配置了简单的注解驱动与注解扫描包....似乎也是没有问题

之后结合该篇文章所说:http://blog.csdn.net/z69183787/article/details/37819831
更深入的了解到了,当web容器启动时候,会初始化两个容器,在容器装配bean时候会根据配置的扫描表进行装配。问题就在这了,对项目的三层所有类扫描会进行两次。

第一次是applicationContext配置对应的容器,第二次是springMVC配置文件对应的子容器。

注意到上述的配置文件:<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> 该段配置事务注解是放在applicationContext中,即只是对父容器中扫描的类具有注解事务功能,在springMVC中的配置并没有配置该内容,所以造成了:

在第一次扫描装配bean时候,bean是具有事务功能的。但是在springmvc二次扫描情况下,会覆盖父类容器中扫描的bean功能,因为没有配置注解驱动,所以就在service代码中不支持事务回滚,尽管加上了事务注解。所以有两种解决方法:

A:在springMVC子容器扫描包的时候,不扫描使用到事务的service层的所有类。在springMVC-servlet.xml中配置:

	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" >
	  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />    
	</tx:annotation-driven>
这样就不会将具有事务功能的service层的类进行扫描和功能覆盖。


B:将父类applicationContext.xml配置文件中的事务注解驱动配置代码:<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> 

从父类配置文件中剪切到子容器springMVC-servlet.xml中,这样,在子容器进行bean装配扫描时候,就具备了事务功能。

	<!-- 设置需要进行Spring注解扫描的类包 -->
	<context:component-scan base-package="com.cybbj" />
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

至此...............done.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值