Spring transaction REQUIRED vs REQUIRES_NEW : Rollback Transaction

159,422

Solution 1

Using REQUIRES_NEW is only relevant when the method is invoked from a transactional context; when the method is invoked from a non-transactional context, it will behave exactly as REQUIRED - it will create a new transaction.

That does not mean that there will only be one single transaction for all your clients - each client will start from a non-transactional context, and as soon as the the request processing will hit a @Transactional, it will create a new transaction.

So, with that in mind, if using REQUIRES_NEW makes sense for the semantics of that operation - than I wouldn't worry about performance - this would textbook premature optimization - I would rather stress correctness and data integrity and worry about performance once performance metrics have been collected, and not before.

On rollback - using REQUIRES_NEW will force the start of a new transaction, and so an exception will rollback that transaction. If there is also another transaction that was executing as well - that will or will not be rolled back depending on if the exception bubbles up the stack or is caught - your choice, based on the specifics of the operations. Also, for a more in-depth discussion on transactional strategies and rollback, I would recommend: «Transaction strategies: Understanding transaction pitfalls», Mark Richards.

Solution 2

If you really need to do it in separate transaction you need to use REQUIRES_NEW and live with the performance overhead. Watch out for dead locks.

I'd rather do it the other way:

  • Validate data on Java side.
  • Run everyting in one transaction.
  • If anything goes wrong on DB side -> it's a major error of DB or validation design. Rollback everything and throw critical top level error.
  • Write good unit tests.
Share:
159,422
Majid Laissi
Author by

Majid Laissi

Updated on July 08, 2022

Comments

  • Majid Laissi
    Majid Laissi almost 2 years

    I have a method that has the propagation = Propagation.REQUIRES_NEW transactional property:

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createUser(final UserBean userBean) {
        //Some logic here that requires modification in DB
    }
    

    This method can be called multiple times simultaneously, and for every transaction if an error occurs than it's rolled back (independently from the other transactions).

    The problem is that this might force Spring to create multiple transactions, even if another one is available, and may cause some performance problems.


    Java doc of propagation = Propagation.REQUIRED says: Support a current transaction, create a new one if none exists.

    This seems to solve the performance problem, doesn't it?

    What about the rollback issue ? What if a new method call rolls back while using an existing transaction ? won't that rollback the whole transaction even the previous calls ?

    [EDIT] I guess my question wasn't clear enough:

    We have hundreds of clients connected to our server.

    For each client we naturally need to send a feedback about the transaction (OK or exception -> rollback).

    My question is: if I use REQUIRED, does it mean only one transaction is used, and if the 100th client encounters a problem the 1st client's transaction will rollback as well ?

  • Majid Laissi
    Majid Laissi over 11 years
    We have hundreds of clients connected to our server. For each client we need to send a feedback about the transaction (OK or exception -> rollback). My question remains: if I use REQUIRED, does it mean only one transaction is used, and if the 100th client encounters a problem the first client's transaction will rollback ?
  • vels4j
    vels4j almost 7 years
    Can you please look at this question stackoverflow.com/questions/44539861/…? do I need REQUIRES_NEW , response given back after pesist done later some time it got rolled back.
  • Ravik
    Ravik about 5 years
    your clients connected to the server will be via separate threads and each thread will have its own transaction. Exception in one thread will not have any impact on the transaction of other thread.