2012-01-26 61 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个文件或其他例如逻辑限制。

相关问题