SpringMVC+Spring事物失效問題

一、spring掃描配置 springmvc掃描配置致使事物失效spring

一個項目中既有SpringMVC又有Spring 的時候,會發生事物失效問題express

緣由:使用的spring註解+springMVC註解,默認狀況下spring應該先加載applicationContext.xml,以後再加載springMVC-servlet.xml而二者都配置了component-scan,spring是父容器springmvc是子容器,子容器掃描的配置範圍不該該大於父容器的範圍mvc

在主容器中(applicationContext.xml),將Controller的註解排除掉 app

1spa

2.net

3code

<context:component-scan base-package="com"component

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

</context:component-scan>xml

而在springMVC配置文件中將Service註解給去掉 

1

2

3

4

<context:component-scan base-package="com"

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

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

</context:component-scan>

由於spring的context是父子容器,因此會產生衝突,由ServletContextListener產生的是父容器,springMVC產生的是子容器,子容器Controller進行掃描裝配時裝配了@Service註解的實例,而該實例理應由父容器進行初始化以保證事務的加強處理,因此此時獲得的將是原樣的Service(沒有通過事務增強處理,故而沒有事務處理能力。 

還有一種方式是將service層改用xml配置,其實這樣作也是變相的讓springmvc沒法掃描service,而只能依賴父窗口也就是ServletContextListener來進行初始化,這樣一樣被賦予了事務性。 

 

 

 

一.聲明式事務配置:

  1. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  2.     <property name="dataSource" ref="dataSource" />  
  3. </bean>  
  4.    <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  5.    <tx:attributes>  
  6.          <tx:method name="add*" propagation="REQUIRED" read-only="false"/>  
  7.          <tx:method name="del*" propagation="REQUIRED" read-only="false"/>  
  8.          <tx:method name="get*" propagation="REQUIRED" read-only="true"/>  
  9.          <tx:method name="mod*" propagation="REQUIRED" read-only="false" />            
  10.    </tx:attributes>  
  11.    </tx:advice>  
  12.    <aop:config>     
  13.     <aop:pointcut id="serviceMethods" expression="execution(public * com.lexing.platform.service.*.*(..))" />  
  14.     <aop:advisor  advice-ref="txAdvice" pointcut-ref="serviceMethods"/>  
  15.    </aop:config>  


二.聲明式事務失效,緣由

根本緣由:由子容器掃描裝配了@Service 註解的實例。

spring的context是父子容器,由ServletContextListener 加載spring配置文件產生的是父容器,springMVC加載配置文件產生的是子容器,子容器對Controller進行掃描裝配時裝配了@Service註解的實例 (@Controller 實例依賴@Service實例),而該實例理應由父容器進行初始化以保證事務的加強處理,因此此時獲得的將是原樣的Service(沒有通過事務增強處理,故而沒有事務處理能力。

三.解決辦法

1.spring配置文件applicationContext中:

  1. <!-- 不掃描帶有@Controller註解的類 ,讓 springMVC 子容器加載。  
  2. <context:component-scan base-package="com.lexing.platform">     
  3.     <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>     
  4. </context:component-scan>    

2.springMVC配置文件 servlet-context.xml中

<!-- 將 帶有 @Service註解的類,交由spring 父容器實例化,[ @Service實例依賴@Repository實例,故spring父容器也會裝配<span style="font-family: Arial, Helvetica, sans-serif;">@Repository 實例</span><span style="font-family: Arial, Helvetica, sans-serif;">]</span>  

  1. <context:component-scan base-package="com.lexing.platform">     
  2.     <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>     
  3. </context:component-scan>     
相關文章
相關標籤/搜索