Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring @Transactional annotation

Tags:

java

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
}

My java code

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

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.

like image 629
user373201 Avatar asked Jan 26 '12 15:01

user373201


People also ask

What is the use of @transactional annotation in Spring?

The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.

What does the @transactional annotation mean?

The @Transactional annotation is metadata that specifies that an interface, class, or method must have transactional semantics; for example, "start a brand new read-only transaction when this method is invoked, suspending any existing transaction".

What is @transactional in Java Spring?

The TransactionStatus interface provides a simple way for transactional code to control transaction execution and query transaction status. Sr.No. This method returns whether this transaction internally carries a savepoint, i.e., has been created as nested transaction based on a savepoint.

What is the use of @transactional annotation in Java?

Transactional annotation provides the application the ability to declaratively control transaction boundaries on CDI managed beans, as well as classes defined as managed beans by the Java EE specification, at both the class and method level where method level annotations override those at the class level.


1 Answers

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
    }

}

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.

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

like image 76
Tomasz Nurkiewicz Avatar answered Sep 25 '22 01:09

Tomasz Nurkiewicz