ssm框架下配置声明事务正确就是不起作用

本文详细探讨了Spring框架中事务管理的问题,特别是当SpringMVC和Spring分别管理不同的bean时,如何确保事务能够正确地回滚。通过调整配置文件,实现了预期的事务回滚效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关键点:spring MVC 和 spring 是两个管理,自动扫描service 的bean必须在spring的配置文件中。 默认前提是:声明事务和配置没有问题,就是不回滚。

环境代码介绍:

springMVC配置文件:

<span style="white-space:pre">		</span><!-- 注解扫描包 -->
		<context:component-scan base-package="com.baidu" />
		<!-- 开启注解 -->
		<mvc:annotation-driven />

spring 的配置文件:(没有扫描任何包文件,有spring全部扫描并加载)

<span style="white-space:pre">		</span><bean id="transactionManager"	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
			<property name="dataSource" ref="dataSource"></property>
		</bean>


		<!-- 5. 使用声明式事务transaction-manager:引用上面定义的事务管理器	 	-->
	<span style="white-space:pre">	</span><tx:annotation-driven transaction-manager="transactionManager" />   

web.xml配置文件:

	<!-- 配置监听器加载spring -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
  	<!-- 配置spring 加载spring的配置文件-->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring-common.xml</param-value><span style="white-space:pre">	</span>
	</context-param>
<span style="white-space:pre">	</span><!-- 配置springmvc 并加载spring的配置文件-->
	<servlet>
		<servlet-name>springMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-mvc.xml</param-value>
		</init-param>
		<!-- 配置随着容器的启动创建springMVC -->
		<load-on-startup>1</load-on-startup>
	</servlet>
  <span style="white-space:pre">	</span><servlet-mapping>
    <span style="white-space:pre">		</span><servlet-name>springMVC</servlet-name>
    <span style="white-space:pre">		</span><url-pattern>/</url-pattern>
  <span style="white-space:pre">	</span></servlet-mapping>

测试代码:正常的 controller 、service impl、dao、mapper.xml,在serviceimpl加上注解事务,并排除runTimeException 事务不回滚

@Service
@Transactional
public class UserDiaryServiceImpl implements UserDiaryService {

	@Resource
	private UserDiaryDao userDiaryDao;

	/**
	 * 添加用户登录记录
	 */
	
	public void saveLoginUserDiary(UserDiary userDiary) throws Exception {
			
			userDiary.setAddTimes(new Date());
			userDiary.setOperContent("登录");
			userDiary.setOperType(1);
			userDiary.setUserID(14L);
			this.userDiaryDao.saveUserDiary(userDiary);
			throw new RuntimeException("huigun");<span style="white-space:pre">		</span>//理论上该方法抛出运行时异常,上面插入的那条记录应该回滚,实际上没有回滚
	}

debug信息展示:

[DEBUG] 2016-09-07 10:44:21,265 method:org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:843)
DispatcherServlet with name 'springMVC' processing POST request for [/baidu/user/login]
  [DEBUG] 2016-09-07 10:44:21,269 method:org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:222)
Looking up handler method for path /user/login
  [DEBUG] 2016-09-07 10:44:21,275 method:org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:229)
Returning handler method [public java.lang.String com.baidu.controller.LoginController.login(com.baidu.model.UserDiary)]
  [DEBUG] 2016-09-07 10:44:21,275 method:org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:249)
Returning cached instance of singleton bean 'loginController'
  [DEBUG] 2016-09-07 10:44:21,331 method:org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.debug(JakartaCommonsLoggingImpl.java:46)
Creating a new SqlSession
  [DEBUG] 2016-09-07 10:44:21,336 method:org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.debug(JakartaCommonsLoggingImpl.java:46)
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@370bea1e] was not registered for synchronization because synchronization is not active
  [DEBUG] 2016-09-07 10:44:21,372 method:org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:110)
<span style="color:#6633ff;background-color: rgb(255, 255, 255);">Fetching JDBC Connection from DataSource</span>
  [DEBUG] 2016-09-07 10:44:21,373 method:org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:142)
<span style="color:#3333ff;">Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8]</span>
  [DEBUG] 2016-09-07 10:44:21,380 method:org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.debug(JakartaCommonsLoggingImpl.java:46)
<span style="color:#ff0000;">JDBC Connection [com.mysql.jdbc.JDBC4Connection@944e79e] will not be managed by Spring</span>
  [DEBUG] 2016-09-07 10:44:21,382 method:org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.debug(JakartaCommonsLoggingImpl.java:46)
<span style="color:#3333ff;">ooo Using Connection [com.mysql.jdbc.JDBC4Connection@944e79e]</span>
  [DEBUG] 2016-09-07 10:44:21,388 method:org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.debug(JakartaCommonsLoggingImpl.java:46)
==>  Preparing: insert into userdiary ( id,UserID,OperContent,OperType,Addtimes ) values (?,?,?,?,?) 
  [DEBUG] 2016-09-07 10:44:21,410 method:org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.debug(JakartaCommonsLoggingImpl.java:46)
==> Parameters: null, 14(Long), 登录(String), 1(Integer), 2016-09-07 10:44:21.322(Timestamp)
  [DEBUG] 2016-09-07 10:44:21,568 method:org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.debug(JakartaCommonsLoggingImpl.java:46)
<span style="color:#ff0000;">Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@370bea1e]</span>
  [DEBUG] 2016-09-07 10:44:21,569 method:org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:327)
Returning JDBC Connection to DataSource
  [DEBUG] 2016-09-07 10:44:21,576 method:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1595)
Invoking afterPropertiesSet() on bean with name 'index'
  [DEBUG] 2016-09-07 10:44:21,576 method:org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1222)
Rendering view [org.springframework.web.servlet.view.JstlView: name 'index'; URL [/index.jsp]] in DispatcherServlet with name 'springMVC'
  [DEBUG] 2016-09-07 10:44:21,576 method:org.springframework.web.servlet.view.AbstractView.exposeModelAsRequestAttributes(AbstractView.java:376)
Added model object 'userDiary' of type [top.lushunde.model.UserDiary] to request in view with name 'index'
  [DEBUG] 2016-09-07 10:44:21,577 method:org.springframework.web.servlet.view.AbstractView.exposeModelAsRequestAttributes(AbstractView.java:376)
Added model object 'org.springframework.validation.BindingResult.userDiary' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'index'
  [DEBUG] 2016-09-07 10:44:21,581 method:org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:207)
Forwarding to resource [/index.jsp] in InternalResourceView 'index'
  [DEBUG] 2016-09-07 10:44:21,592 method:org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
Successfully completed request
  [DEBUG] 2016-09-07 10:44:21,593 method:org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:249)
Returning cached instance of singleton bean 'sqlSessionFactory'

在错误信息中蓝字红字表示关键信息,其中红字表示作物原因:

<span style="color:#ff0000;">JDBC Connection [com.mysql.jdbc.JDBC4Connection@944e79e] will not be managed by Spring</span>
<span style="color:#ff6666;">是说 链接获取成功但是不能被spring管理。</span>
<span style="color:#ff6666;"></span><pre name="code" class="html"><span style="color:#ff0000;">Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@370bea1e]</span>
<span style="color:#ff0000;">关闭了没有事务的链接。</span>


原因就是:我们xml加载的springMVC配置中扫描了所有的bean,bean有springMVC管理,而我们通过spring添加声明时事务,spring又没有扫描和管理bean,所以事务并不会被spring管理,如debug提示信息所示,

<span style="color: rgb(255, 0, 0);">JDBC Connection [com.mysql.jdbc.JDBC4Connection@944e79e] will not be managed by Spring</span>
没有被spring管理,而是由springMVC管理,这是两个不同的管理域,储存不同地方东西,但是都可以正常注入。


解决方案:

我们将controller的文件有springMVC扫描管理,serivce、dao、intersector等使用spring扫描管理

具体修改配置文件:

springMVC的配置文件:

<!-- 注解扫描包 -->
<context:component-scan base-package="top.lushunde.controller" />
//只扫描contorller下的bean


spring的配置文件:

<!-- 注解扫描包 -->
<context:component-scan base-package="cn.dajean.mb" use-default-filters="false">
//扫描所有的bean
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
     //排除不需要的扫描
</context:component-scan>
////

<!-- 注解扫描包 -->
<context:component-scan base-package="cn.dajean.mb" ></context:component-scan> //扫描所有包

重新启动项目,可以回滚!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值