javapostgresqlconcurrencyspring-data-jpapessimistic-locking

Why Spring Data JPA Pessimistic lock not working as expected?


I'm trying to work with pessimistic locks in Spring Data JPA and Postgresql but pessimistic lock is not working as expected.

Tried to concurrently update a record using pessimistic lock, since pessimistic lock should block until lock is available, was expecting concurrent transactions to block instead of getting error, but when I run the update via multiple threads get the following error:

ERROR 67017 --- [onPool-worker-9] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: could not serialize access due to concurrent update

What am I doing wrong?

Here is my repository implementation:

@Lock(LockModeType.PESSIMISTIC_WRITE)
@Override
public void addToSequence(Integer id) {
    FiveEntity fiveEntity=entityManager.find(FiveEntity.class,id);
    fiveEntity.setSequence(fiveEntity.getSequence()+1);
    log.debug("sequence: {}",fiveEntity.getSequence());
    entityManager.merge(fiveEntity);
}

And here is my service implementation:

@Transactional(isolation = Isolation.SERIALIZABLE)
@Override
public void processWithPessimisticLock() {
   fiveEntityRepository.addToSequence(lastId);
}

Solution

  • That's how PostgreSQL works. SERIALIZABLE will not wait until the other transaction has finished but will throw an exception.

    But as you are already using PESSIMISTIC_WRITE which will result in a SELECT ... FOR UPDATE you don't need to change the isolation level at all.