I have 2 threads calling the same service with potentially the same data that needs to be inserted into a table if not present.
I have a bulk call like this:
@Async
@Transactional(readOnly = false, timeout=100)
public void adoptDealInBulk(List<String> adopters, ....)
This in turn does a loop for each to the adoptDeal call.
@Transactional(timeout=20)
adoptDeal(adopter)
This does a look up first to see if an adoption was created:
adoptionService.findAdoption(adopter)
.... and if not present a create and save: ...
repository.save(adoption);
This is the read to find the adoption:
@Transactional(readOnly = true)
findAdoption(adoption)
Now I've tried on the adoptDeal call:
@Transactional(timeout=Constant.ADOPT_OFFER_TIMEOUT, propagation = Propagation.REQUIRED)
And on the findAdoption
@Transactional(readOnly = true, isolation = Isolation.SERIALIZABLE)
I know its terrible for performance, but shouldn't this prevent the read while the other thread is doing the insert?
However, I still get dupe rows with 2 threads hit this with the same new user to add.
How could I fix the annotations or add something else to prevent the read and also commit one at a time?
Thank you.