Search code examples
springtransactionsspring-transactionspropagation

Spring Transaction Propagation on Class to Class level and Method to Method Level


How Spring Transaction Propagation works for PROPAGATION_REQUIRED and PROPAGATION_REQUIRES_NEW?

Please provide info regarding this propagation on class to class level and method to method level.

I also need to know how these transaction are initialised/started and resumes previous transaction when current transaction completes for PROPAGATION_REQUIRES_NEW.

How transaction will decide when need to commit/rollback when single transaction is used in case of PROPAGATION_REQUIRED and PROPAGATION_REQUIRES_NEW?


Solution

  • Hope this information may help to understand some basic functionality and flow of spring tx propagation.

    This is some basic info about propagation which will you find from some well known resources also, but it is needed to put here first to get some basic idea about Spring Propagation :

    Propagation is the ability to decide how the business methods should be encapsulated in both logical or physical transactions.

    REQUIRED behaviour means that the same transaction will be used if there is an already opened transaction in the current bean method execution context and it creates a new transaction if one already does not exists.

    REQUIRES_NEW behaviour means that a new physical transaction will always be created by the container.

    The NESTED behaviour makes nested Spring transactions to use the same physical transaction but sets save-points between nested invocations so inner transactions may also rollback independently of outer transactions.

    The MANDATORY behaviour states that an existing opened transaction must already exist. If not an exception will be thrown by the container.

    The NEVER behaviour states that an existing opened transaction must not already exist. If a transaction exists an exception will be thrown by the container.

    The NOT_SUPPORTED behaviour will execute outside of the scope of any transaction. If an opened transaction already exists it will be paused.

    The SUPPORTS behaviour will execute in the scope of a transaction if an opened transaction already exists. If there isn't an already opened transaction the method will execute anyway but in a non-transactional way.

    ====================================

    Some of have also doubts that what happen for calling different method from one method within same class if we provide Tx propagation (ex. REQUIRES_NEW):

    No.

    It will not create new Transaction when method call is from method to method within same class. It will use same Transaction. This propagation applies to only method calls from different classes.

    Example:

    <bean id="class2" parent="yourSpringAOPInterceptor">
        <property name="target">
            <bean   class="Class2">
                <property name="prop1" ref="prop1" />
            </bean>
        </property>
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
                <prop key="methodABC">PROPAGATION_REQUIRES_NEW</prop>
            </props>
        </property>
    </bean>
    

    Class2 has below method structure:

    • methodPQR()
    • methodABC()

      1) When any call comes to methodPQR() from outside of class2 then this method uses same transaction of outside caller.

      2) When any call comes to methodABC() from outside of class2 then this method creates new transaction and does not use same transaction of outside caller.

      3) When methodPQR() call methodABC() of same class then methodABC() does not create new transaction and uses same transaction of methodPQR().

    For more Please refer : http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html

    ======================================

    This below picture will help you to understand these things:

    • When second transaction starts than what happens to current running First transaction.

    • How changes are committed when all methods use same transaction. Would most inner method will commit all changes or the most outer method?

    • What happen if second transaction gets any exception? Should it rollback only second transaction or should it rollback first and second both transactions? Same way, if first transaction gets any exception than it will rollback only first transaction or also changes committed by second(new-inner) transaction? - How Spring decides this?

    • How first transaction resumes when second transaction completes?

    enter image description here

    Thanks for reading. Please comments if you find anything wrong or more info on this.