你的位置:首页 > Java教程

[Java教程]spring + mybatis 注解式事务不回滚的原因分析 @Transactional


在一个项目中发现spring的事务无法回滚。

DEBUG: org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@49f9ce55] was not registered for synchronization because synchronization is not activeDEBUG: org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [ConnectionHandle{url=jdbc:postgresql://localhost/mypro, user=mypro, debugHandle=null, lastResetAgoInSec=92, lastUsedAgoInSec=92, creationTimeAgoInSec=92}] will not be managed by Spring

在网上找了好多,都没解决

我搜到的资料相关链接有:

http://www.cnblogs.com/xunux/p/4388124.html

http://www.iteye.com/topic/1123069

http://hwak.iteye.com/blog/1611970

http://blog.csdn.net/will_awoke/article/details/12002705 (最终在这里得到启发,问题解决)

其实,上面几个链接,都提到是包扫描的问题,要在包扫描的配置里加上

<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>

没错,真的是这个问题引起的。

起初,我已经加上了,但问题依旧,问题研究出在哪里呢?????:( :( :((伤心啊!!!)

后来找到这里:http://blog.csdn.net/will_awoke/article/details/12002705,里面有讲到:

Spring容器优先加载由ServletContextListener(对应applicationContext.

好了,问题关键是父容器和子容器的事了。

我细心检查项目中的web.

<context-param>  <param-name>contextConfigLocation</param-name>  <param-value>      /WEB-INF/spring/root-context.</param-value> </context-param>  <filter>  <filter-name>encodingFilter</filter-name>  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  <init-param>   <param-name>encoding</param-name>   <param-value>UTF-8</param-value>  </init-param>  <init-param>   <param-name>forceEncoding</param-name>   <param-value>true</param-value>  </init-param> </filter> <filter-mapping>  <filter-name>encodingFilter</filter-name>  <url-pattern>/*</url-pattern> </filter-mapping> <listener>  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> (说明:这个是产生父容器的,这与上面context-param,contextConfigLocation有关系) </listener> <servlet>  <servlet-name>appServlet</servlet-name>  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  <init-param>   <param-name>contextConfigLocation</param-name>   <param-value>/WEB-INF/spring/appServlet/servlet-context.</param-value> (说明:这个是产生子容器的,即springmvc的ContextApplication是子容器)  </init-param>  <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping>  <servlet-name>appServlet</servlet-name>  <url-pattern>/</url-pattern> </servlet-mapping>

我的项目是maven构建,项目分为mypro-web,和mypro-core两个模块,其中mypro-web依赖mypro-core模块,mypro-core最终打成jar包,放在mypro-web的lib下面。

原因就是我的mypro-web和mypro-core中都有applicationContext-mypro.

<!-- 事务管理器配置,单数据源事务 -->  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >    <property name="dataSource" ref="dataSource" />  </bean>  <!-- 支持注解式事务 -->  <tx:annotation-driven transaction-manager="transactionManager" />

所以,我猜这导致spring在构建事务声明时,出问题了,

把mypro-web中的applicationContext-mypro.