Search code examples
javaspringjpatransactional

@Transactional, method inside method


I have a Service with a method calling another method. In the first method, I perform only queries with SELECT, but they have to see the INSERTS and UPDATES done in the second method.

Then, I have to deal with transactions. I'm using Spring, so I can use the @Transactional annotation.

Which of the following options seems to be more correct for you?

Option A

@Transactional
public void generate(){
    // selects
    save(a);
    // more selects
}

@Transactional
public void save(Object a){
    //save the object
}

Option B

public void generate(){
    // selects
    save(a);
    // more selects
}

@Transactional
public void save(Object a){
    //save the object
}

Thanks!!


Solution

  • I will answer myself after a bit of researching. Tell me something if you think I'm wrong :P

    First of all, I think both options are correct, depending on your business logic. I mean, a method should be Transactional when it have to be all done in a same transaction, and this depends for the programmer and the business logic.

    For example, Option A is correct if the 'generate' method contains logic to be done in the same Transaction, so if something in the generate method fails, all the changes are undone. In this case, the Transactional annotation in the save method is not necessary.

    Option A

    @Transactional
    public void generate(){
        // selects
        save(a);
        // more selects
    }
    
    //@Transactional
    public void save(Object a){
        //save the object
    }
    

    Option B is also correct if your Transaction, depending on your business logic, is only in the save method. But there is something wrong in Option B if you are using Spring and AOP (Aspects). Spring uses proxies when using AOP, so if you need to call a save method with a Transactional annotation, you have to use the proxy to let Spring call the save method within a Transaction.

    Option B

    private MyClass self; // this is the proxy bean of this class!
    
    public void generate(){
        // selects
        self.save(a);
        // more selects
    }
    
    @Transactional
    public void save(Object a){
        //save the object
    }