Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring transaction REQUIRED vs REQUIRES_NEW : Rollback Transaction

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 ?

like image 457
Majid Laissi Avatar asked Oct 24 '12 14:10

Majid Laissi


People also ask

What is the difference between required and Requires_new?

REQUIRED, spring checks for any existing transaction. If yes, it uses that old transaction otherwise it creates a new one. But, the disadvantage of Propagation. REQUIRES_NEW is that even if the inner method fails to execute (because of some exception), the outer method commits the transaction.

Is @transactional required in Spring boot?

When the propagation is MANDATORY, if there is an active transaction, then it will be used. If there isn't an active transaction, then Spring throws an exception: @Transactional(propagation = Propagation. MANDATORY) public void mandatoryExample(String user) { // ... }

What happens when a method annotated with @transaction propagation Requires_new is invoked?

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.

Is @transactional required?

if it's using proxy based configuration to declare and access to DAO layer, the method into DAO class must be annotated with @Transactional too. If you have added @Transactional to your service layer, there is no further requirement to also add @Transactional to the DAO methods being called within that transaction.


2 Answers

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.

like image 173
Eugen Avatar answered Sep 21 '22 09:09

Eugen


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.
like image 44
Piotr Gwiazda Avatar answered Sep 21 '22 09:09

Piotr Gwiazda