春天@Transactional注释 [英] spring @Transactional annotation

查看:112
本文介绍了春天@Transactional注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象类和两个扩展它的子类.我在spring配置文件中有以下内容

I have an abstract class and two sub classes that extend it. I have the following in spring config file

<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" />

在我的抽象类中,我有以下方法

In my abstract class I have the following methods

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中.

This does not work. executeInsertUpdateQuery() executes just one native sql query. If I put @Transactional on imortDataToDB() it works but then it makes my transaction huge since inside that method I loop through all the rows in a file and insert the records in db.

推荐答案

这是Spring的主要陷阱之一-如果您在同一个类中通过非事务方法调用@Transactional-方法 >,@Transactional被忽略(除非您使用AspectJ编织).这不是Spring本身的问题 -EJB具有相同的缺点.

This is one of the major pitfalls in Spring - if you call @Transactional-method from non-transactional method in the same class, the @Transactional is ignored (unless you use AspectJ weaving). This is not Spring problem per se - the EJB has the same shortcomings.

不幸的是,使用基于接口的代理和基于类的代理,您所能做的就是将您的班级一分为二:

Unfortunately with interface-based and class-based proxies all you can do is to split your class in two:

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
    }

}

整个过程都是由Spring内部实施AOP代理引起的.使用上面的代码,每次您从非事务性BeanA调用b.executeInsertUpdateQuery()时,都会启动新事务.

The whole hustle is caused by the internal implementation of AOP proxies in Spring. With the code above new transaction will be started every time you call b.executeInsertUpdateQuery() from non-transactional BeanA.

我在我的博客春季陷阱:代理中对此进行了描述, 春季AOP谜语Spring AOP谜语已被揭密.

I wrote about it on my blog Spring pitfalls: proxying, Spring AOP riddle and Spring AOP riddle demystified.

这篇关于春天@Transactional注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆