1. 程式人生 > >SSM-@Transactional 註釋不生效

SSM-@Transactional 註釋不生效

ica data update public auto count 覆蓋 autowire ref

1.在applicationConext.xml 中配置事務註解驅動

<!-- 事務註解驅動 --> 
        <tx:annotation-driven /> 
         <!-- 配置事務 -->
       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="basicDataSource"
/> </bean>

2.Service中做如下配置

@Service
public class AccountService {
    @Autowired
    AccountMapper am;
    
    @Transactional
    public void zhuanZhang(Integer fromAcct,Integer toAcct,Double money){
        //先減去fromAcct 的錢
        am.updateMoneyByAcctNumber(fromAcct, money*(-1));
        System.out.println(
"先減去fromAcct 的錢"+money*(-1)); System.out.println(10/0); //再加上toAcct 上的錢 am.updateMoneyByAcctNumber(toAcct, money); System.out.println("再加上toAcct 上的錢"+money); } }

3.Springmvc.xml 中包掃描的配置如下

<!-- 配置包掃描 -->
               <
context:component-scan base-package="cn.zen.controller.*,cn.zen.service" />

4.結果測試事務報錯回滾的時候不成功。

查看框架的啟動日誌看到 Spring沒有接管JDBC事務的報錯

JDBC Connection [jdbc:mysql://*****, MySQL-AB JDBC Driver] will not be managed by Spring

5.解決方式是

將帶有事務註解的包放到ApplicationContext.xml 中掃描,同時在springmvc.xml 中剔除該包的掃描。

百度了一下具體原因,相對明晰的說法:

Spring容器優先加載由ServletContextListener,對應applicationContext.xml 產生的父容器,而SpringMVC(對應spring-mvc.xml)產生的是子容器。
子容器Controller進行掃描裝配時裝配的@Service註解的實例是沒有經過事務加強處理,即沒有事務處理能力的Service,而父容器進行初始化的Service是保證事務的增強處理能力的。如果不在子容器中將Service exclude掉,此時得到的將是原樣的無事務處理能力的Service。

據此得到兩個結論:

1.Spring 才能處理事務,Springmvc 不行。
2..子容器回覆蓋父容器中的相同配置,所以要在包註解掃描的時候在子容器中將Service exclude掉

SSM-@Transactional 註釋不生效