Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring JPA atomic get or create method

I'm using Spring Boot and JPA (with Hibernate).

I have a method (into my service) to:

  • Check if already there into the DB a specific entity (for example I need to check if already have an user. For this I using a custom JPQL query into my JPA repository.
  • After this, in case there isn't any result for the previous step, I will create the entry into the DB (using the the save JPA repository method) At the same time I need to create an other entity also (for example some info related to the user stored into a separated table). So, in this case I will have two create-query (one for User table and one for Info-User table).
  • In case already have some results for the step 1, I need to skip the insert step obviously.

Obviously, I need to guarantee the atomicity for this method.

I must to avoid separate transactions that risk creating duplicate entries in the DB.

An additional note: on the Users table I cant to add some unique constraints because there are some different combinations for this (for example, I can create again the same user if the status is in a certain value or something like this).

I tried to use only the @Transactional annotation for my method but I noticed this is not enough (using some stress test I'm able to create multiple rows into the DB).

So now I'm confused.

What's the best practice to have an atomic method? Have I to change the Transaction Isolation level? Have I to use some Locks?

I'm not a Spring expert but I think that this is a common problem but I'm not able to understand what is the correct way.

Basically I'm looking for an atomic GET_OR_CREATE method using the JPA (and JPA repository)

like image 555
Safari Avatar asked Jul 28 '26 11:07

Safari


1 Answers

In that case you will need to set the Transaction isolation level to SERIALIZABLE that only one transaction can access the database. This can be done using the isolation attribute of the Transactional annotation:

@Transactional(isolation = Isolation.SERIALIZABLE)
public void yourMethod(){
    // ...
}

Read more about that topic here: https://www.baeldung.com/spring-transactional-propagation-isolation

like image 139
Simon Martinelli Avatar answered Jul 30 '26 00:07

Simon Martinelli



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!