2

We have a Spring Boot application with a controller class that is called from the clients and interacts with the DB. Based on a condition, the controller checks if a record for a unique value exists or not, if not, it creates a new record (with auto-generated primary key) and save it.

Now concurrency issue is in this condition:

Two different objects of class A want an object of class B with value b1, both of them check at the same time in the DB, they get null, now they try to create a new object of class B with value b1, here comes error.

I tried using, simple double-locking method,

final static Object lock = new Object();

public Object handle(cs cs, Map<String, Object> headers){
    LOGGER.info(" persisting message : " + cs.getcsCode());

    F f = repo.findByQuery();
    if (f==null ) {
        synchronized(lock) {
            f = repo.findByQuery;

            if (f==null ) {
                repo.save(cs.getF1());
            }
        }
    }

    return csRepo.save(cs);
}

but later realized that my application runs on two JVMs, which use a common database. After going through some questions, I came to another option ,

@Transacational(isolation=REPEATABLE_READ)

But I am not sure if it will work in my scenario, as its explanation says, it is useful when modifying data on a row, but I am creating a new row. As this is a rare scenario and involves multiple JVMs, I can’t test it to be sure.

manish
  • 19,695
  • 5
  • 67
  • 91
HimanshuR
  • 1,390
  • 5
  • 16
  • 35
  • Reagaring this [answer](https://stackoverflow.com/a/4036063/2838289) repeatable read is not sufficient. Your transaction needs the isolation level _serializable_. – LuCio Aug 22 '18 at 12:22
  • Will it be enough or it will need something else to handle two jvms – HimanshuR Aug 22 '18 at 19:43
  • I haven't used the _serializable_ isolation level yet. But reading the description I would say it doesn't matter which VM opens such a transaction. So as of my understanding you could test it by even opening two such transactions in one VM. – LuCio Aug 22 '18 at 19:56
  • Is it not possible to put a unique constraint on the database table that corresponds to `class B`, let duplicate inserts fail, and catch and handle a `ConstraintViolationException` in the code? – manish Aug 23 '18 at 07:33
  • why the key that you use in the query `repo.findByQuery()` for finding the record `f` is not marked as unique in the database schema? The other insertion will fail because of the check for uniqueness. – chalda Sep 18 '18 at 21:18

0 Answers0