0

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.

Kunal
  • 398
  • 2
  • 4
  • 18
  • 1
    Try locking mechanisms: https://vladmihalcea.com/2015/01/12/a-beginners-guide-to-java-persistence-locking/ Sample: https://stackoverflow.com/questions/16159396/how-to-enable-lockmodetype-pessimistic-write-when-looking-up-entities-with-sprin – Ish Oct 18 '17 at 21:15
  • Your database should protect against this. – Namphibian Oct 19 '17 at 01:06

0 Answers0