在一個項目中發現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://m.survivalescaperooms.com/xunux/p/4388124.html
http://m.survivalescaperooms.com/topic/1123069
http://hwak.VEvb.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文件刪除,問題解決!!!
新聞熱點
疑難解答