1. 程式人生 > >關於Spring事務配置不起作用問題總結

關於Spring事務配置不起作用問題總結

實際開發環境中經常會遇到Spring框架配置事物失敗或不起作用問題,而且無法直觀的在程式碼中追根溯源。工程師們絞盡腦汁,檢查各項配置引數、檢視日誌、反向推理等等手段去排除問題所在。本文就將出現最為頻繁的常見問題總結分析:

目錄

資料庫非事務支援引擎導致

使用Spring框架配置事務,其最終落實還是資料庫的支援,如果專案所使用資料庫不支援事務配置那自然配置失敗。以MySQL為例常用的資料庫引擎有InnoDB和MyISAM。其中InnoDB支援事務,MyISAM不支援。所以如果當前資料庫表不是InnoDB的話需要修改過來,修改語句為:alert table [表名] type = InnoDB;

使用context:component-scan重複掃描導致

在配置檔案中經常看見如下程式碼:

<context:component-scan base-package="com.lst.*"/>

事務的植入層一般都是通過代理類,而一般情況下這個代理類是不需要掃描的。上述程式碼,會將com.lst下的所有檔案包統統掃描一次。所以,這時候最容易出現事務配置不起作用的問題。
建議修改方式,如:

<context:component-scan base-package="com.lst.*" >
        <context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Service" /> </context:component-scan>

因為我們通常會將事務層配置到Impl類中,並註解@Service註解作為代理實現類。該程式碼含義即為當掃描com.lst.下的所有檔案包時,排除標記@Service註解代理類。這樣就避免了事務不起作用問題。

事務配置錯誤

這類錯誤算是粗心或者對Spring事務配置不熟悉導致,這裡我將事務基本配置寫出來,可做模板參考。
1、配置事務管理器

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>

2、配置事務(註解方式)

<tx:annotation-driven transaction-manager="transactionManager" / >

2、配置事務(攔截器方式)

<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" read-only="false"
                rollback-for="java.lang.Exception" no-rollback-for="" />
            <tx:method name="create*" propagation="REQUIRED" read-only="false"
                rollback-for="java.lang.Exception" no-rollback-for="" />
            <tx:method name="do*" propagation="REQUIRED" read-only="false"
                rollback-for="java.lang.Exception" no-rollback-for="" />
            <tx:method name="process*" propagation="SUPPORTS" />
            <tx:method name="*" propagation="SUPPORTS" />
        </tx:attributes>
    </tx:advice>

3、引入AOP

<aop:config>
    <aop:pointcut id="transactionPointcut" expression="execution( * com.lst..service.*.*(..))" />
    <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
</aop:config>

代理方法必須是公共函式(public標誌)

由Spring的AOP的特殊決定,入口函式必須是public,否則事務不起作用。當然這個問題實際開發中很少出現,因為定義的介面預設許可權就是public。