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);
}
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.