前言:
公司最近一个项目用到Spring和Mybatis,发现用起来挺方便,比以前的那个struts+hibernate舒服多了。废话少说,直接摆问题,碰到的问题是,mybatis不在事务中运行,后台日志报 “Closing no transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@19006c9]”错误。无论是加了@Transactional注解和是没加都报这个信息。一个方法中插入多条数据,某次插入失败也不回滚。
问题描述:
环境: Spring 3.1.0 + Mybatis 3.1.0 + mybatis-spring 1.0.0 RC3 + DB2 9.5 + Tomcat 6.0.35
web工程名称: isap
配置文件:applicationContext.xml + isap-servlet.xml
先看配置信息:
applicationContext.xml
01 |
<? xml version = "1.0" encoding = "UTF-8" ?>
|
02 |
< beans xmlns = "http://www.springframework.org/schema/beans"
|
03 |
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
|
04 |
xmlns:tx = "http://www.springframework.org/schema/tx"
|
05 |
xmlns:context = "http://www.springframework.org/schema/context"
|
07 |
http://www.springframework.org/schema/beans
|
08 |
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
09 |
http://www.springframework.org/schema/tx
|
10 |
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
|
11 |
http://www.springframework.org/schema/context
|
12 |
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
16 |
< bean id = "dataSource" class = "org.springframework.jndi.JndiObjectFactoryBean" >
|
17 |
< property name = "jndiName" >
|
18 |
< value >java:comp/env/jndi_isap</ value >
|
22 |
< bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" >
|
23 |
< property name = "configLocation" value = "classpath:config/mybatis-config.xml" ></ property >
|
24 |
< property name = "dataSource" ref = "dataSource" />
|
25 |
< property name = "mapperLocations" >
|
27 |
< value >classpath:com/cosbulk/isap/*/dao/mapper/*Mapper.xml</ value >
|
32 |
< bean id = "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" >
|
33 |
< property name = "dataSource" ref = "dataSource" />
|
34 |
< qualifier value = "isap" />
|
38 |
< tx:annotation-driven transaction-manager = "transactionManager" />
|
40 |
< bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer" >
|
41 |
< property name = "sqlSessionFactory" ref = "sqlSessionFactory" />
|
42 |
< property name = "basePackage" value = "com.cosbulk.isap" ></ property >
|
48 |
< bean id = "smisDataSource" class = "org.springframework.jndi.JndiObjectFactoryBean" >
|
49 |
< property name = "jndiName" >
|
50 |
< value >java:comp/env/jndi_smis</ value >
|
53 |
< bean id = "smisSqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" >
|
54 |
< property name = "configLocation" value = "classpath:config/mybatis-config.xml" ></ property >
|
55 |
< property name = "dataSource" ref = "smisDataSource" />
|
56 |
< property name = "mapperLocations" >
|
58 |
< value >classpath:com/cosbulk/smis/dao/mapper/*Mapper.xml</ value >
|
62 |
< bean id = "smisTransactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" >
|
63 |
< property name = "dataSource" ref = "smisDataSource" />
|
64 |
< qualifier value = "smis" />
|
67 |
< tx:annotation-driven transaction-manager = "smisTransactionManager" />
|
69 |
< bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer" >
|
70 |
< property name = "sqlSessionFactory" ref = "smisSqlSessionFactory" />
|
71 |
< property name = "basePackage" value = "com.cosbulk.smis" ></ property >
|
在applicationContext.xml文件中,主要配置了数据源和dao接口以及mapper文件相关信息,其他的bean信息在isap-servlet.xml文件中定义。
配置文件: isap-servlet.xml
01 |
<? xml version = "1.0" encoding = "UTF-8" ?>
|
02 |
< beans xmlns = "http://www.springframework.org/schema/beans"
|
03 |
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:p = "http://www.springframework.org/schema/p"
|
04 |
xmlns:context = "http://www.springframework.org/schema/context"
|
05 |
xmlns:mvc = "http://www.springframework.org/schema/mvc"
|
07 |
http://www.springframework.org/schema/beans
|
08 |
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
09 |
http://www.springframework.org/schema/context
|
10 |
http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
11 |
http://www.springframework.org/schema/mvc
|
12 |
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"
|
13 |
default-autowire = "byName" >
|
15 |
< span style = "color:#ff0000;" >< strong >
|
16 |
< context:component-scan base-package = "com.cosbulk.isap" >
|
17 |
< context:exclude-filter type = "regex" expression = "com.cosbulk.isap.*.*.model" />
|
18 |
< context:exclude-filter type = "regex" expression = "com.cosbulk.isap.*.*.dao.*" />
|
19 |
</ context:component-scan >
|
21 |
< context:component-scan base-package = "com.cosbulk.smis" >
|
22 |
< context:exclude-filter type = "regex" expression = "com.cosbulk.smis.*.*.model" />
|
23 |
< context:exclude-filter type = "regex" expression = "com.cosbulk.smis.*.*.dao.*" />
|
24 |
</ context:component-scan ></ strong ></ span >
|
25 |
< mvc:annotation-driven />
|
29 |
< bean class = "com.cosbulk.isap.common.interceptor.CheckLoginInterceptor" />
|
33 |
< bean id = "multipartResolver" class = "org.springframework.web.multipart.commons.CommonsMultipartResolver" >
|
34 |
< property name = "defaultEncoding" value = "UTF-8" />
|
39 |
< bean id = "exceptionResolver" class = "org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" >
|
40 |
< property name = "defaultErrorView" >
|
41 |
< value >errorPages/error</ value >
|
43 |
< property name = "defaultStatusCode" >
|
46 |
< property name = "warnLogCategory" >
|
47 |
< value >org.springframework.web.servlet.handler.SimpleMappingExceptionResolver</ value >
|
49 |
< property name = "exceptionMappings" >
|
51 |
< prop key = "org.springframework.web.multipart.MaxUploadSizeExceededException" >errorPages/maxUploadExceeded</ prop >
|
57 |
< bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" >
|
58 |
< property name = "viewClass" value = "org.springframework.web.servlet.view.JstlView" />
|
59 |
< property name = "prefix" value = "/view/" />
|
60 |
< property name = "suffix" value = ".jsp" />
|
在这个配置文件里进行了所有的注解(@Controller、@Service等)扫描和mvc相关配置。
事务场景:
Service层通过注解@Transactional注入事务
03 |
@Transactional ( "isap" )
|
04 |
public class UserService{
|
06 |
private UserDao userDao;
|
13 |
return userDao.getId();
|
21 |
public void updateUser(User user,Map<String,Object> param) {
|
23 |
userDao.updateUser(user);
|
25 |
userDao.deleteUserRole(param);
|
29 |
insertUserRole(param);
|
测试过几次updateUser的调用,事务就是不起作用的,后台log信息如下:
1 |
DEBUG 2011 - 09 - 04 16 : 19 : 46 , 672 org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl: JDBC Connection [org.apache.commons.dbcp.PoolableConnection @67aece ] will not be managed by Spring
|
3 |
DEBUG 2011 - 09 - 04 16 : 19 : 46 , 672 org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl: SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession @19006c9 ] was not registered for synchronization because synchronization is not active
|
5 |
DEBUG 2011 - 09 - 04 16 : 19 : 46 , 687 org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl: Committing JDBC Connection [org.apache.commons.dbcp.PoolableConnection @67aece ]
|
7 |
DEBUG 2011 - 09 - 04 16 : 19 : 46 , 687 org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl: Closing no transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession @19006c9 ]
|
9 |
DEBUG 2011 - 09 - 04 16 : 19 : 46 , 687 org.springframework.jdbc.datasource.DataSourceUtils: Returning JDBC Connection to DataSource
|
解决方案:
1、配置文件的问题吧? (见http://www.iteye.com/topic/1123069)
03 |
< context:component-scan base-package = "com.kimho" >
|
04 |
< context:exclude-filter type = "annotation" expression = "org.springframework.stereotype.Controller" />
|
05 |
</ context:component-scan >
|
07 |
2、servlet-context.xml: |
09 |
< context:component-scan base-package = "com.kimho" >
|
10 |
< context:exclude-filter type = "annotation" expression = "org.springframework.stereotype.Service" />
|
11 |
</ context:component-scan >
|
我做了相应的修改,把isap-servlet里的bean扫描拆成了两部分,分别放入applicationContext.xml和isap-servlet.xml文件中。
applicationContext.xml中加入:
2 |
< context:component-scan base-package = "com.cosbulk.isap" >
|
3 |
< context:include-filter type = "annotation" expression = "org.springframework.stereotype.Service" />
|
4 |
</ context:component-scan >
|
6 |
< context:component-scan base-package = "com.cosbulk.smis" >
|
7 |
< context:include-filter type = "annotation" expression = "org.springframework.stereotype.Service" />
|
8 |
</ context:component-scan >
|
isap-servlet.xml文件中,扫描bean部分换成:
2 |
< context:component-scan base-package = "com.cosbulk.isap" >
|
3 |
< context:exclude-filter type = "annotation" expression = "org.springframework.stereotype.Service" />
|
4 |
</ context:component-scan >
|
6 |
< context:component-scan base-package = "com.cosbulk.smis" >
|
7 |
< context:exclude-filter type = "annotation" expression = "org.springframework.stereotype.Service" />
|
8 |
</ context:component-scan >
|
重启服务器测试,发现效果和之前一样,事务还是没起作用。开始以为是和包扫描的位置有关,于是把扫描的位置放到文件末尾,发现还是没有起作用。最后偶然一个想法clean了下tomcat,然后重启,居然事务有效了。
总结: 修改完配置文件后,clean下工程,重启加载新的配置文件。OK,问题解决。
2、如果按照你的步骤设置为ID为null的话,那么就需要捕获mybatis抛出的异常,然后在catch语句中抛出一个Exception,这个时候Spring容器的事务管理就会起作用,会回滚事务。
3、如果用mysql数据库,数据库表你如果是自动建表,那么就需要把建表的Engine设置为InnoDB格式,自动建表的格式为:MyISAM,这中格式的是不支持事务管理的。
总结下: Spring在使用ContextLoadListener加载applicationContext.xml或其他名称的xml文件时,能进行数据源和相关事务注解的检查,启动事务特性。若在isap-servlet.xml文件中加载是,仅作为普通bean定义加载。所以一个良好的习惯就是,分层配置相关的bean。applicationContext.xml中配置数据库相关的bean(dao、service等), isap-servlet中配置mvc相关的bean(controller等)。
转自:http://blog.csdn.net/walkerjong/article/details/7839002
2012-04-26 11:17 1350人阅读 收藏 举报
用spring aop配置了事务,但是不起作用,困扰了好久。
事务配置如下:
<!-- 配置事务管理器,使用jdbc事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 申明式事务 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="allManagerMethod" expression="execution(* com.xiu.xclk.web.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" />
</aop:config>
查网上,有的说是因为spring mvc自动扫描的时候,把包括@service的注解一下都扫描今天了,所以在开始的时候要先排除掉对@service注解的扫描,见帖子:http://www.linuxso.com/architecture/14904.html
配置好之后,事务还是不起作用,很奇怪,之后查找,一个帖子给了很大的启发:http://hi.baidu.com/jakoes/blog/item/7256efc2c7ec30190ff477dc.html,说是Spring的事务实现采用基于AOP的拦截器来实现,如果没有在事务配置的时候注明回滚的checked exception,我的代码中抛的是java.lang.Exception,改成抛RuntimeException,事务起作用了。帖子中说两种办法可以解决:
1,在事务属性后面加上需要回滚的checked exception。比如<prop key="save*">PROPAGATION_REQUIRED,-XXXXException</prop>(注意那个"-",对应的是"+")
2, 不改配置文件,将需要事务回滚的异常继承自unchecked exception类,也就是RuntimeException。
那么对于第二种方法,我的是起作用了,但是第一种方法我的是声明了对Exception回滚了啊。后来一想,是不是要写全java类名啊,于是改成:
<tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>,这样就起作用了。看来还是自己大意了,spring的配置文件要写全类名的。
相关推荐
SSM整合指的是Spring、SpringMVC和MyBatis三个开源框架的集成,它们共同构建了一个强大的Java Web开发解决方案。在Java后端开发中,SSM框架因其灵活性、可扩展性和良好的社区支持而广受欢迎。接下来,我们将深入探讨...
这三个框架各自解决不同的问题,但结合在一起能提供一个完整的Java Web应用解决方案。 1. **Spring**:是一个轻量级的Java开发框架,它主要提供了依赖注入和面向切面编程等功能,极大地简化了Java企业级应用的开发...
Spring框架是Java开发中不可或...总结来说,Spring框架提供了全面的解决方案,涵盖了Web应用的各个方面,包括控制层、数据访问层、事务管理、缓存等。了解并熟练掌握这些知识点对于成为一名专业的Java开发者至关重要。
【SSM社区疫情联防联控系统】是一个综合性的信息技术解决方案,主要应用于社区对新冠疫情的防控工作。系统采用Java技术栈,结合Spring、SpringMVC和MyBatis(SSM框架)进行开发,同时整合了SpringBoot框架以提高开发...
8. **MyBatis面试题**:MyBatis是一个优秀的持久层框架,面试中可能会讨论动态SQL、映射文件、事务管理、缓存机制以及MyBatis与Spring的整合使用。 这些面试题的涵盖范围广泛,旨在考察候选人的理论知识、实践经验...
15. **分布式系统**:CAP理论,分布式锁,负载均衡,分布式缓存(Redis,Memcached),消息队列(RabbitMQ,Kafka),以及分布式事务的解决方案。 以上就是Java面试中可能涉及的主要知识点,每个主题都包含了大量的...
最后,对于企业级应用,Spring框架的使用越来越普遍,它的依赖注入、AOP(面向切面编程)、MyBatis整合、Spring Boot、Spring Cloud等相关知识也是面试中不可或缺的部分。 总的来说,这份2017版的Java面试题汇总...
总的来说,基于SSM的防疫信息登记系统是利用现代Java技术实现的信息化解决方案,它有效整合了前后端资源,提高了防疫工作的效率和准确性。对于学习和理解Java Web开发,以及如何构建实用的防疫信息系统,都有很高的...
这个系统旨在为高校提供一套有效的疫情监控和管理解决方案。 【SSM框架详解】 1. Spring:这是一个全面的Java企业级应用开发框架,提供了依赖注入(DI)、面向切面编程(AOP)以及事务管理等功能,简化了开发过程。...
无纸化考试模拟系统是一种利用现代信息技术,实现线上考试、成绩管理、学生信息管理的教育信息化解决方案。本系统基于Spring、SpringMVC和MyBatis(SSM)框架,结合MySQL数据库,构建了一个高效、稳定且易于维护的...
17. Dubbo配置文件如何加载到Spring中:通过XML配置或注解方式将Dubbo配置整合到Spring应用中。 以上所述知识点仅是文档中提及的一部分,面试题通常还会包含更多细节和深入理解的内容,掌握这些知识点对于Java...
- **Spring框架**:用于企业级应用的全面解决方案,包括依赖注入、事务管理、AOP等。 - **Hibernate**或MyBatis:作为ORM(对象关系映射)工具,简化数据库操作。 - **Servlet和JSP**:处理HTTP请求,构建动态网页。...
计算机图书管理系统是一个典型的信息化解决方案,它整合了图书的采购、分类、借阅、归还以及库存管理等多个环节,旨在提高图书馆的工作效率和服务质量。在这个压缩包文件“计算机图书管理系统.zip”中,我们可以推测...