I'm trying to find an entity from the db, do some modification and then save it, when I run 3-5 jobs at the same time everything works fine, but during concurrent run with 15+ jobs, I see there is always one job failed with optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException:StaleObjectStateException: Row was updated or deleted by another transaction
and other jobs finished with success. Here is what i want to achieve in my code:
public void myConcurrentRnnningJob(){
// here the primary key id was generated with an UUID generator
Optional<myEntity> entity = repository.findById(request.getId());
log.info("found entity");
myEntity.ifPresent(entity -> {
//set some values in entity, then save
...
log.save("saving entity");
repository.save(entity); <- this line is printed in the error log
});
I noticed that when the exception is thrown, both "found entity" and "saving entity" logs have the exact same timestamp, and my findById() and save() methods are:
@Transactional(readOnly = true)
@Repository
public interface RequestsRepository extends CrudRepository<Request, UUID>) {
@Override
Optional<RequestEntity> findById(UUID id);
@Lock(LockModeType.PESSIMISTIC_WRITE)
@QueryHints({ @QueryHint(name = "javax.persistence.lock.timeout", value = "-2") }) // skip locked
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
<T extends RequestEntity> T save(@NotNull T entity);
}
I don't know why the above error happens and if the issue is caused by saving and finding the record at the same time.