Search code examples
javaspring-mvcspring-transactions

@Transactional Spring chaining and self invoking


I want to know the potential side effects of chaining @Transactional method calls calling from a private method from the same class. From researching this seems to be a limitation from Spring and can cause side effects but what if the corresponding class calls as separate class that also has the @Transactional Annotation? If B fails, does B rollback and A?

@Service
public class A {
    @Autowired
    private B myB;

    @Transactional
    private void transactionA(){
        myB.transactionB();
    }

    public void doTransactionA() {
        transactionA();
    }
}

@Service
public class B {
    @Transactional
    private void transactionB(){
        //throw an exception
    }
}

Solution

  • First of all.

    When using proxies, you should apply the @Transactional annotation only to methods with public visibility

    So keep that in mind if you only want to run on the standard Java Proxies.
    Any other case is covered by CGLIB.

    Anyway that depends. The @Transactional annotation supports transaction propagation.

    • PROPAGATION_REQUIRED: a logical transaction scope is created for each method upon which the setting is applied. Basically each "nested" method call will join an existing transaction, if any.
    • PROPAGATION_REQUIRES_NEW: uses a completely independent transaction for each affected transaction scope. Each annotated method has its own transaction.
    • PROPAGATION_NESTED: uses a single physical transaction with multiple savepoints that it can roll back to. Basically if a nested call fails, only that one is rolled back, and execution continues.

    For a better overview, see docs.