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)