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 active

DEBUG: 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.xml)產生的父容器,而SpringMVC(對應mvc_dispatcher_servlet.xml)產生的是子容器。子容器Controller進行掃描裝配時裝配的@Service注解的實例是沒有經過事務加強處理,即沒有事務處理能力的Service,而父容器進行初始化的Service是保證事務的增強處理能力的。如果不在子容器中將Service exclude掉,此時得到的將是原樣的無事務處理能力的Service,因為在多上下文的情況下,如果同一個bean被定義兩次,后面一個優先。

好了,問題關鍵是父容器和子容器的事了。

我細心檢查項目中的web.xml配置

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
            /WEB-INF/spring/root-context.xml
            classpath:/applicationContext-*.xml
            classpath:/applicationContext-mypro.xml
            classpath:/applicationContext-core.xml
        </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.xml</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.xml這個配置文件(這兩個文件里面的東西是一樣的),這個文件里就配了事務相關的東西。

<!-- 事務管理器配置,單數據源事務 -->
    <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.xml文件刪除,問題解決!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM