Search code examples
javaspringdatabase-connectionspring-annotationstransactional

Multiple Spring @Transactional annotations in one application?


Within my application I have several @Transactional annotations on different methods.

They use the Crud Repository to carry out deletes on my database. I am wondering at what stage do these deletes get carried out, and do I need all the @Transactional annotations?

For example, 2 delete methods that are later called in a façade method, the façade method is then called in the runner:

1. method 1:

@Transactional
public void deleteFromSchemaOne(){

}

1. method 2:

@Transactional
public void deleteFromSchemaTwo(){

}

2. Calling these 2 methods in a façade method:

@Transacational
public void deleteFromAllSchemas(){

deleteFromSchemaOne();
deleteFromSchemaTwo();

}

3. Calling the façade method in the runner

@Transactional
    public void run(String... args) throws Exception {

        service.deleteFromAllSchemas();


}

What I would like to know is:

What stage will my deletes actually be carried out? Will it be when the method is completed within the Runner?

EDIT:

Façade method with loop:

public void deleteFromAllSchemas() {

    for(int i = 0; i < list.size(); i++){

     deleteFromSchemaOne();
     deleteFromSchemaTwo();

    }

}


Solution

  • When the outermost transaction finishes, so after run(). Actually it's not the outermost, it's the only transaction. The inner @Transactionals don't create a new transaction, they just join the existing one.

    If you need to make sure that some changes are committed even before the outer transaction finishes, you need to set the propagation of the transaction with @Transactional(propagation=Propagation.REQUIRES_NEW). This will create a new transaction even if there is one that already exists.

    In your example code (at least based on what it contains now), the run() method probably shouldn't even start a transaction.

    If I understood you correctly, you want something along the lines of

    public void run() {
        for(int i = 0;i < list.size(); i++)
            service.deleteFromAllSchemas(i);
    }
    
    @Transactional
    public void deleteFromAllSchemas(int i) {
        deleteFromSchemaOne(i);
        deleteFromSchemaTwo(i);
    }