2012-01-26 60 views
5

我有一個抽象類和兩個子類來擴展它。我在Spring配置文件spring @Transactional註釋

<bean id="importConfigFile" class="xxx.ImportConfigFiles" parent="parentImportFile"></bean> 

<bean id="importFile" class="xxx.ImportUMTSKPIFiles" parent="parentImportFile"></bean> 

<bean id="parentImportFile" name="parentImportFile" class="xxx.ImportUMTSFiles" abstract="true"></bean> 

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

以下在我的抽象類,我有以下方法

public void importDataToDB(){ 
    //all the good stuff goes in here 
} 

@Transactional 
public void executeInsertUpdateQuery(){ 
    //all the good stuff goes in here 
} 

我的Java代碼

ImportConfigFiles importConfigFiles = (ImportConfigFiles)context.getBean("importConfigFile"); 
importConfigFiles.setFileLocation(destPath); 
importConfigFiles.importDataToDB(); 

這是行不通的。 executeInsertUpdateQuery()只執行一個本地sql查詢。如果我將@Transactional放在imortDataToDB()上,它可以工作,但是這會使我的事務變得很大,因爲在該方法中,我循環遍歷文件中的所有行並將記錄插入到db中。

回答

8

這是春季的主要缺陷之一 - 如果你調用從非事務性方法@Transactional - 方法在同一類,則@Transactional被忽略(除非你使用AspectJ織)。這不是Spring問題本身 - EJB具有相同的缺點。不幸的是與基於類的接口和基於代理

所有你能做的就是一分爲二類:

public class BeanA() { 

    @Resource 
    private BeanB b; 

    public void importDataToDB(){ 
     b.executeInsertUpdateQuery(); 
    } 
} 

public class BeanB { 

    @Transactional 
    public void executeInsertUpdateQuery(){ 
     //all the good stuff goes in here 
    } 

} 

整個喧囂由春天內部實現AOP代理造成的。隨着上面的代碼新交易將開始每次您從非交易BeanAb.executeInsertUpdateQuery()

我在博客上寫了關於它Spring pitfalls: proxyingSpring AOP riddleSpring AOP riddle demystified

+0

感謝您的快速響應。 – user373201

0

不太確定,問題是什麼,但@Transactional將整個方法封裝在一個事務中,所以顯然如果在一個方法中導入所有內容將會很大。優點是,如果在某個地方導入失敗,整個事務將不會被執行,並且數據庫中沒有錯誤數據。

如果你不想這樣做,你必須自己管理事務或者爲數據子集調用@Transactional註解方法,就像你現在正在做一次導入一樣,但也許你會這樣做爲10個文件或其他例如邏輯限制。

相關問題